Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added handling for links (hyperlinks). #27

Merged
merged 3 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,11 @@ dist
# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
874 changes: 874 additions & 0 deletions .yarn/releases/yarn-3.6.1.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-3.6.1.cjs
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ FROM pdf_base as pdf_debug
# So do nothing app related as the files won't
# be present yet.

FROM node:14 as pdf_build
FROM node:18 as pdf_build

WORKDIR /src
COPY package.json .
COPY yarn.lock .
COPY tslint.json .
COPY tsconfig.json .
RUN yarn install --frozen-lockfile
COPY .yarnrc.yml .
COPY .yarn ./.yarn
RUN yarn --immutable

COPY src ./src
COPY fonts ./fonts

RUN yarn build

# remove development dependencies
RUN npm prune --production

# run node prune
RUN npx node-prune

FROM node:14 as pdf_release
FROM node:18 as pdf_release

# Run everything after as non-privileged user.
RUN install -m 775 -d /usr/src/app
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@
"tslint": "^6.0.0",
"tslint-react": "^4.2.0",
"typescript": "^4"
}
},
"volta": {
"node": "18.17.0",
"yarn": "3.6.1"
},
"packageManager": "yarn@3.6.1"
}
2 changes: 2 additions & 0 deletions src/factory/ElementRegistry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createListElement } from './Elements/ListElementFactory';
import { createPageElement } from './Elements/PageElementFactory';
import { createShadowElement } from './Elements/ShadowElementFactory';
import { ILogger } from '../ILogger';
import { createLinkElement } from './Elements/LinkElementFactory';

// Define the function signature that we use to create elements
export type ElementFactoryFunction = (e: any, factory:IElementFactory, context:IElementContext, stack: string[], logger:ILogger) => Promise<React.ReactElement | React.ReactElement[]>;
Expand Down Expand Up @@ -40,4 +41,5 @@ staticElementRegistry.register('view', createViewElement);
staticElementRegistry.register('list', createListElement);
staticElementRegistry.register('shadow', createShadowElement);
staticElementRegistry.register('page', createPageElement);
staticElementRegistry.register('link', createLinkElement);

53 changes: 53 additions & 0 deletions src/factory/Elements/LinkElementFactory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { LinkElementDeclaration } from '../../wire/ElementDeclaration';
import { IElementFactory } from '../IElementFactory';
import { IElementContext } from '../IElementContext';
import { Link, Text } from '@react-pdf/renderer';
import React from 'react';
import { ILogger } from '../../ILogger';
import { v4 } from 'uuid';
import { finalizeBoolean } from '../../helpers/FinalizeHelpers';
import { createElementKey } from '../createElementKey';

// Create a link element


export const createLinkElement = async (element: LinkElementDeclaration, factory: IElementFactory, context: IElementContext, stack: string[], logger: ILogger): Promise<React.ReactElement> => {
const { style, text, classes, debug, href, children } = element;

// Calculate the final style to apply considering any class names included
const finalStyle = context.buildFinalStyle(classes ?? [], style ?? {});
const mustBreak = finalizeBoolean(element.break, context);
const canWrap = finalizeBoolean(element.wrap, context);
const isFixed = finalizeBoolean(element.fixed, context);
const finalText = context.finalizeString(text ?? "");
const finalHref = context.finalizeString(href ?? "");

// We create a render function, rather than just a simple string, so that we can account for
// dynamic functionality, such as including page numbers.
logger.debug(`<Link> ${href} ${text}`);
if(children?.length && text?.length)
{
logger.error('Text element provided with both a text property and a children property. Text will be discarded.');
}

if (finalStyle.fontFamily && !context.fontIsRegistered(finalStyle.fontFamily)) {
await context.loadReferencedFonts(finalStyle.fontFamily);
}

const key = createElementKey('link', element);
const renderedChildren = text?.length ? [<Text>{finalText}</Text>] : await Promise.all(children!.map(async (child, idx) => {
return await factory.createElement(child, [...stack, key+`.child[${idx}]`]);
}));

return (
<Link
key={v4()}
style={finalStyle}
wrap={canWrap}
debug={context.config.debug || debug}
fixed={isFixed}
break={mustBreak}
src={finalHref}
>{renderedChildren}</Link>
);
};
3 changes: 3 additions & 0 deletions src/factory/Elements/TextElementFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,6 @@ export const createTextElement = async (element: TextElementDeclaration, factory
/>
);
};



11 changes: 10 additions & 1 deletion src/wire/ElementDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
Orientation,
} from '@react-pdf/types';

export type ElementTypes = 'view'|'image'|'text'|'list'|'shadow'|'page';
export type ElementTypes = 'view'|'image'|'text'|'list'|'shadow'|'page'|'link';

export type StyleWithShadow = Style & {
shadowColor?:string,
Expand Down Expand Up @@ -77,6 +77,15 @@ export interface TextElementDeclaration extends StylableElementDeclaration
children?: TextElementDeclaration[] | undefined;
}

export interface LinkElementDeclaration extends StylableElementDeclaration
{
type?: 'link';
href?:string;
wrap?:boolean;
text?:string;
children?: AnyElementDeclaration[] | undefined;
}

export interface ImageElementDeclaration extends StylableElementDeclaration
{
type?: 'image';
Expand Down
Loading
Loading