mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +00:00
feat: render server-side invoice pdf template using React server
This commit is contained in:
19
shared/pdf-templates/src/lib/layout/Box.tsx
Normal file
19
shared/pdf-templates/src/lib/layout/Box.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React, { forwardRef, Ref } from 'react';
|
||||
import { SystemProps, x } from '@xstyled/emotion';
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
}
|
||||
export interface BoxProps
|
||||
extends SystemProps,
|
||||
IProps,
|
||||
Omit<React.HTMLProps<HTMLDivElement>, 'color' | 'as'> { }
|
||||
|
||||
export const Box = forwardRef(
|
||||
({ className, ...rest }: BoxProps, ref: Ref<HTMLDivElement>) => {
|
||||
const Element = x.div;
|
||||
|
||||
return <Element className={className} ref={ref} {...rest} />;
|
||||
},
|
||||
);
|
||||
Box.displayName = '@bigcapital/Box';
|
||||
58
shared/pdf-templates/src/lib/layout/Group.tsx
Normal file
58
shared/pdf-templates/src/lib/layout/Group.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { SystemProps } from '@xstyled/emotion';
|
||||
import { Box } from './Box';
|
||||
import { filterFalsyChildren } from './utils';
|
||||
|
||||
export type GroupPosition = 'right' | 'center' | 'left' | 'apart';
|
||||
|
||||
export const GROUP_POSITIONS = {
|
||||
left: 'flex-start',
|
||||
center: 'center',
|
||||
right: 'flex-end',
|
||||
apart: 'space-between',
|
||||
};
|
||||
|
||||
export interface GroupProps
|
||||
extends SystemProps,
|
||||
Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
|
||||
/** Defines justify-content property */
|
||||
position?: GroupPosition;
|
||||
|
||||
/** Defined flex-wrap property */
|
||||
noWrap?: boolean;
|
||||
|
||||
/** Defines flex-grow property for each element, true -> 1, false -> 0 */
|
||||
grow?: boolean;
|
||||
|
||||
/** Space between elements */
|
||||
spacing?: number;
|
||||
|
||||
/** Defines align-items css property */
|
||||
align?: React.CSSProperties['alignItems'];
|
||||
}
|
||||
|
||||
export function Group({
|
||||
position = 'left',
|
||||
spacing = 20,
|
||||
align = 'center',
|
||||
noWrap,
|
||||
children,
|
||||
...props
|
||||
}: GroupProps) {
|
||||
const filteredChildren = filterFalsyChildren(children);
|
||||
|
||||
return (
|
||||
<Box
|
||||
boxSizing={'border-box'}
|
||||
display={'flex'}
|
||||
flexDirection={'row'}
|
||||
alignItems={align}
|
||||
flexWrap={noWrap ? 'nowrap' : 'wrap'}
|
||||
justifyContent={GROUP_POSITIONS[position]}
|
||||
gap={`${spacing}px`}
|
||||
{...props}
|
||||
>
|
||||
{filteredChildren}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
33
shared/pdf-templates/src/lib/layout/Stack.tsx
Normal file
33
shared/pdf-templates/src/lib/layout/Stack.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
import { x, SystemProps } from '@xstyled/emotion';
|
||||
|
||||
export interface StackProps
|
||||
extends SystemProps,
|
||||
Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
|
||||
/** Key of theme.spacing or number to set gap in px */
|
||||
spacing?: number;
|
||||
|
||||
/** align-items CSS property */
|
||||
align?: React.CSSProperties['alignItems'];
|
||||
|
||||
/** justify-content CSS property */
|
||||
justify?: React.CSSProperties['justifyContent'];
|
||||
}
|
||||
|
||||
export function Stack({
|
||||
spacing = 20,
|
||||
align = 'stretch',
|
||||
justify = 'top',
|
||||
...restProps
|
||||
}: StackProps) {
|
||||
return (
|
||||
<x.div
|
||||
display={'flex'}
|
||||
flexDirection="column"
|
||||
justifyContent="justify"
|
||||
gap={`${spacing}px`}
|
||||
alignItems={align}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
5
shared/pdf-templates/src/lib/layout/utils.ts
Normal file
5
shared/pdf-templates/src/lib/layout/utils.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
export const filterFalsyChildren = (children: React.ReactNode) => {
|
||||
return React.Children.toArray(children).filter(Boolean);
|
||||
};
|
||||
4
shared/pdf-templates/src/lib/main.ts
Normal file
4
shared/pdf-templates/src/lib/main.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './layout/Stack';
|
||||
export * from './layout/Group';
|
||||
export * from './layout/Box';
|
||||
export * from './text/Text';
|
||||
5
shared/pdf-templates/src/lib/text/Text.tsx
Normal file
5
shared/pdf-templates/src/lib/text/Text.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { x } from '@xstyled/emotion';
|
||||
|
||||
export const Text = ({ children }: { children: React.ReactNode }) => {
|
||||
return <x.div>{children}</x.div>;
|
||||
};
|
||||
Reference in New Issue
Block a user