Skip to content

Commit

Permalink
feat: add PDF component library
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbert committed Sep 9, 2024
1 parent 2d5a517 commit 8d63b35
Show file tree
Hide file tree
Showing 34 changed files with 1,997 additions and 24 deletions.
28 changes: 28 additions & 0 deletions packages/component-library-pdf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- @license CC0-1.0 -->

# Component library voor PDF-bestanden

## Installatie

Draai het volgende script in de terminal om de software te installeren die HTML naar PDF converteert, [Prince XML](http://princexml.com).

```sh
cd packages/component-library-pdf
pnpm run install-prince
```

## Testen

Wanneer een nieuwe Prince XML versie uit komt, dan moet alles opnieuw getest worden. Alle bestaande tests op basis van sha256 hashes zullen falen, omdat de gebruikte software onderdeel is van de gegenereerde PDF-bestanden. Bijvoorbeeld:

```xml
<pdf:Producer>Prince 15.4 (www.princexml.com)</pdf:Producer>
```

Bekijk elke test in `*.test.tsx`. Bekijk het PDF document dat correspondeert met het `id` in de test. Bijvoorbeeld voor de `id: "pdf-paragraph"` staat het resultaat in `tmp/pdf-paragraph.pdf`. Als het resultaat goed is, kopieer dan de code uit `tmp/pdf-paragraph.pdf.sha256` naar `toBe('...')`. Als de test niet slaagt, dan mag je oude sha256 hash laten staan.

## Relevante links

- [Tagged PDF Best Practice Guide: Syntax For developers implementing ISO 14289-1 (PDF/UA) — PDF download](https://pdfa.org/wp-content/uploads/2019/06/TaggedPDFBestPracticeGuideSyntax.pdf)
- [Deterministic output: a way to specify the PDF File Identifier (/ID) property](https://www.princexml.com/forum/topic/4931/deterministic-output-a-way-to-specify-the-pdf-file?p=1#24826)
- [Convert PDF to HTML](https://pdfix.io/convert-pdf-to-html/). Gebruik de optie "Layout defined by PDF Tags" om te zien welke tags er in een PDF zitten, via de developer tools. Bijvoorbeeld: `data-pdf-se-type-original="Link"`.
9 changes: 9 additions & 0 deletions packages/component-library-pdf/TESTPLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Tesplan voor PDF componenten

## Heading 1

Bron: [tmp/heading-1.html](tmp/heading-1.html)
PDF: [tmp/heading-2.html](tmp/heading-2.html)

- [ ] Heading 1 ziet er uit als een heading 1
- [ ] Heading 1 is zichtbaar in table of contents van PDF
20 changes: 20 additions & 0 deletions packages/component-library-pdf/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Config } from 'jest';

const config: Config = {
coverageProvider: 'v8',
extensionsToTreatAsEsm: ['.ts', '.tsx'],
rootDir: './src/',
transform: {
'^.+\\.(ts|tsx)?$': [
'ts-jest',
{
useESM: true,
},
],
},
transformIgnorePatterns: ['node_modules'],

verbose: true,
};

export default config;
53 changes: 53 additions & 0 deletions packages/component-library-pdf/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"version": "0.0.0",
"author": "Community for NL Design System",
"description": "PDF component library bundle for the Municipality of Utrecht based on the NL Design System architecture",
"license": "EUPL-1.2",
"name": "@utrecht/component-library-pdf",
"keywords": [
"nl-design-system"
],
"private": true,
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git+ssh",
"url": "[email protected]:nl-design-system/utrecht.git",
"directory": "packages/component-library-pdf"
},
"scripts": {
"clean": "rimraf dist/",
"install-prince": "( cd node_modules/prince && npm run install )",
"lint-build": "tsc --noEmit --project tsconfig.json",
"prince": "node_modules/prince/prince/lib/prince/bin/prince",
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
"test:watch": "jest --watch"
},
"files": [
"dist/"
],
"devDependencies": {
"@babel/plugin-transform-runtime": "7.24.7",
"@babel/preset-react": "7.24.7",
"@jest/globals": "29.7.0",
"@testing-library/jest-dom": "6.4.5",
"@testing-library/react": "15.0.7",
"@types/node": "20.14.8",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@utrecht/component-library-css": "workspace:*",
"@utrecht/component-library-react": "workspace:*",
"@utrecht/design-tokens": "workspace:*",
"cross-env": "7.0.3",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"prince": "1.11.6",
"react": "18.3.1",
"react-dom": "18.3.1",
"rimraf": "5.0.7",
"ts-jest": "29.2.4",
"tsx": "4.19.0",
"typescript": "5.5.4"
}
}
21 changes: 21 additions & 0 deletions packages/component-library-pdf/src/Article.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { Article, Paragraph } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Article', () => {
it('renders a <Art> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-article',
render: () => (
<Article>
<Paragraph>The quick brown fox jumps over the lazy dog</Paragraph>
</Article>
),
});

expect(sha256).toBe('3a94e1e570c85d3c0d1c35589b65a6f1a690e8c581bed5a217d4713abc2d1dac');
});
});
21 changes: 21 additions & 0 deletions packages/component-library-pdf/src/Blockquote.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { Blockquote, Paragraph } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Blockquote', () => {
it('renders a <BlockQuote> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-blockquote',
render: () => (
<Blockquote>
<Paragraph>The quick brown fox jumps over the lazy dog.</Paragraph>
</Blockquote>
),
});

expect(sha256).toBe('1565b0f7dd9ae4121654f76836cba952321e1d3110c7a910f2563d18a664eda8');
});
});
17 changes: 17 additions & 0 deletions packages/component-library-pdf/src/Checkbox.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { Checkbox } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Checkbox', () => {
it('renders a <Form> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-checkbox',
render: () => <Checkbox />,
});

expect(sha256).toBe('16860207ce8377c3b11bd31d676efba22d10f8eedacdf9098b702c2743fc512b');
});
});
21 changes: 21 additions & 0 deletions packages/component-library-pdf/src/Code.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { Code, Paragraph } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Code', () => {
it('renders a <Code> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-code',
render: () => (
<Paragraph>
Use <Code>{'/* Hello world */'}</Code> to create a code comment.
</Paragraph>
),
});

expect(sha256).toBe('f8104c20620bcf4c4e9a63f83c88d32841fef9f6ec481fb3de238d97997d134a');
});
});
28 changes: 28 additions & 0 deletions packages/component-library-pdf/src/CodeBlock.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { CodeBlock } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Code block', () => {
it('renders a <Code> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-code-block',
render: () => (
<CodeBlock>{`<!DOCTYPE html>
<html lang="nl" dir="ltr">
<head>
<title>NL Design System</title>
<meta charset="utf-8"/>
</head>
<body>
<h1>NL Design System</h1>
</body>
</html>`}</CodeBlock>
),
});

expect(sha256).toBe('46986780cbaeba8d2b585dc2d244f68a273121c8e831f1dba10912c968cfc0a8');
});
});
42 changes: 42 additions & 0 deletions packages/component-library-pdf/src/DataList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-env jest */

import { beforeAll, describe, expect, it } from '@jest/globals';
import { DataList, DataListItem, DataListKey, DataListValue } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Data list', () => {
let sha256: string;

beforeAll(async () => {
({ sha256 } = await renderPdf({
id: 'pdf-data-list',
render: () => (
<DataList>
<DataListItem>
<DataListKey>Pangram</DataListKey>
<DataListValue>The quick brown fox jumps over the lazy dog</DataListValue>
</DataListItem>
</DataList>
),
}));
});

it('renders a <L> tag', async () => {
expect(sha256).toBe('1ef37478b0c027f45c557c94ca9c4d237860baf121f02d482e45b85c43348134');
});

describe('list item', () => {
it('renders a <LI> tag', async () => {
expect(sha256).toBe('1ef37478b0c027f45c557c94ca9c4d237860baf121f02d482e45b85c43348134');
});

it('renders a <Lbl> tag with the key', async () => {
expect(sha256).toBe('1ef37478b0c027f45c557c94ca9c4d237860baf121f02d482e45b85c43348134');
});

it('renders a <LBody> tag with the value', async () => {
expect(sha256).toBe('1ef37478b0c027f45c557c94ca9c4d237860baf121f02d482e45b85c43348134');
});
});
});
22 changes: 22 additions & 0 deletions packages/component-library-pdf/src/FormFieldTextbox.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { FormFieldTextbox } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Form field with textbox', () => {
it('renders a <Form> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-form-field-textbox',
render: () => (
<FormFieldTextbox
label="Postcode"
description="Nederlandse postcode met 4 cijfers en 2 letters, bijvoorbeeld: 1234 AB."
></FormFieldTextbox>
),
});

expect(sha256).toBe('d79ea42074650594beb4266345e09cabeb9a437ed13d66ac6f40527b715ec62b');
});
});
17 changes: 17 additions & 0 deletions packages/component-library-pdf/src/FormLabel.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { FormLabel } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Form label', () => {
it.skip('renders a <Lbl> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-form-label',
render: () => <FormLabel>Name</FormLabel>,
});

expect(sha256).toBe('');
});
});
37 changes: 37 additions & 0 deletions packages/component-library-pdf/src/Heading.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import {
Heading1,
Heading2,
Heading3,
Heading4,
Heading5,
Heading6,
Paragraph,
} from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Heading with variable heading level', () => {
it.skip('renders a <H7> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-heading',
render: () => (
<>
<Heading1>Heading 1: The quick brown fox jumps over the lazy dog</Heading1>
<Heading2>Heading 2: The quick brown fox jumps over the lazy dog</Heading2>
<Heading3>Heading 3: The quick brown fox jumps over the lazy dog</Heading3>
<Heading4>Heading 4: The quick brown fox jumps over the lazy dog</Heading4>
<Heading5>Heading 5: The quick brown fox jumps over the lazy dog</Heading5>
<Heading6>Heading 6: The quick brown fox jumps over the lazy dog</Heading6>
<Paragraph role="heading" aria-level={7}>
Heading 7: The quick brown fox jumps over the lazy dog
</Paragraph>
</>
),
});

expect(sha256).toBe('');
});
});
17 changes: 17 additions & 0 deletions packages/component-library-pdf/src/Heading1.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { Heading1 } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Heading 1', () => {
it('renders a <H1> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-heading-1',
render: () => <Heading1>Heading 1: The quick brown fox jumps over the lazy dog</Heading1>,
});

expect(sha256).toBe('f7922ee3cbbe73b7aff8b2532aedacb6a254f2b673591b360b6656154a18b6ba');
});
});
22 changes: 22 additions & 0 deletions packages/component-library-pdf/src/Heading2.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { Heading1, Heading2 } from '@utrecht/component-library-react';
import React from 'react';
import { renderPdf } from './lib';

describe('Heading 2', () => {
it('renders a <H2> tag', async () => {
const { sha256 } = await renderPdf({
id: 'pdf-heading-2',
render: () => (
<>
<Heading1>Heading 1: The quick brown fox jumps over the lazy dog</Heading1>
<Heading2>Heading 2: The quick brown fox jumps over the lazy dog</Heading2>
</>
),
});

expect(sha256).toBe('8facfd10a62f642565c95c1c69575d3cbc81f841c9a69fc230ec5d2e85410c4d');
});
});
Loading

0 comments on commit 8d63b35

Please sign in to comment.