diff --git a/.changeset/warm-pigs-sell.md b/.changeset/warm-pigs-sell.md new file mode 100644 index 000000000..43a4f8406 --- /dev/null +++ b/.changeset/warm-pigs-sell.md @@ -0,0 +1,5 @@ +--- +"@react-pdf/layout": patch +--- + +fix: layout package types diff --git a/packages/layout/src/svg/replaceDefs.ts b/packages/layout/src/svg/replaceDefs.ts index d2edecdcf..b94f3ffc5 100644 --- a/packages/layout/src/svg/replaceDefs.ts +++ b/packages/layout/src/svg/replaceDefs.ts @@ -30,10 +30,13 @@ const parseNodeDefs = (node: SafeNode): SafeNode => { const props = node.props; - const fill = `fill` in props ? replaceDef(defs, props?.fill) : undefined; + const fill = + `fill` in props ? replaceDef(defs, props?.fill as any) : undefined; const clipPath = - `clipPath` in props ? replaceDef(defs, props?.clipPath) : undefined; + `clipPath` in props + ? replaceDef(defs, props?.clipPath as any) + : undefined; const newProps = Object.assign({}, node.props, { fill, clipPath }); diff --git a/packages/layout/src/types/base.ts b/packages/layout/src/types/base.ts index 804453b57..54174ce61 100644 --- a/packages/layout/src/types/base.ts +++ b/packages/layout/src/types/base.ts @@ -1,5 +1,8 @@ import { YogaNode } from 'yoga-layout/load'; import * as React from 'react'; +import { SafeClipPathNode } from './clip-path'; +import { SafeLinearGradientNode } from './linear-gradient'; +import { SafeRadialGradientNode } from './radial-gradient'; export type YogaInstance = { node: { create: () => YogaNode }; @@ -34,17 +37,17 @@ export type Origin = { top: number; }; -export interface ExpandedBookmark { +export interface Bookmark { title: string; top?: number; left?: number; zoom?: number; fit?: true | false; expanded?: true | false; + parent?: number; + ref?: number; } -export type Bookmark = string | ExpandedBookmark; - export type DynamicPageProps = { pageNumber: number; totalPages?: number; @@ -82,7 +85,26 @@ export type NodeProps = { bookmark?: Bookmark; }; -export interface SVGPresentationAttributes { +export type FillRule = 'nonzero' | 'evenodd'; + +export type TextAnchor = 'start' | 'middle' | 'end'; + +export type StrokeLinecap = 'butt' | 'round' | 'square'; + +export type StrokeLinejoin = 'butt' | 'round' | 'square'; + +export type Visibility = 'visible' | 'hidden' | 'collapse'; + +export type DominantBaseline = + | 'auto' + | 'middle' + | 'central' + | 'hanging' + | 'mathematical' + | 'text-after-edge' + | 'text-before-edge'; + +export type SVGPresentationAttributes = { fill?: string; color?: string; stroke?: string; @@ -91,22 +113,34 @@ export interface SVGPresentationAttributes { opacity?: string | number; strokeWidth?: string | number; fillOpacity?: string | number; - fillRule?: 'nonzero' | 'evenodd'; + fillRule?: FillRule; strokeOpacity?: string | number; - textAnchor?: 'start' | 'middle' | 'end'; - strokeLinecap?: 'butt' | 'round' | 'square'; - strokeLinejoin?: 'butt' | 'round' | 'square'; - visibility?: 'visible' | 'hidden' | 'collapse'; + textAnchor?: TextAnchor; + strokeLinecap?: StrokeLinecap; + strokeLinejoin?: StrokeLinejoin; + visibility?: Visibility; clipPath?: string; - dominantBaseline?: - | 'auto' - | 'middle' - | 'central' - | 'hanging' - | 'mathematical' - | 'text-after-edge' - | 'text-before-edge'; -} + dominantBaseline?: DominantBaseline; +}; + +export type SafeSVGPresentationAttributes = { + fill?: string | SafeLinearGradientNode | SafeRadialGradientNode; + color?: string; + stroke?: string; + transform?: string; + strokeDasharray?: string; + opacity?: number; + strokeWidth?: number; + fillOpacity?: number; + fillRule?: FillRule; + strokeOpacity?: number; + textAnchor?: TextAnchor; + strokeLinecap?: StrokeLinecap; + strokeLinejoin?: StrokeLinejoin; + visibility?: Visibility; + clipPath?: SafeClipPathNode; + dominantBaseline?: DominantBaseline; +}; export interface FormCommonProps extends NodeProps { name?: string; diff --git a/packages/layout/src/types/canvas.ts b/packages/layout/src/types/canvas.ts index 64bb43711..1c02e849d 100644 --- a/packages/layout/src/types/canvas.ts +++ b/packages/layout/src/types/canvas.ts @@ -1,7 +1,8 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; +import { YogaNode } from 'yoga-layout/load'; -import { NodeProps, Origin } from './base'; +import { Box, NodeProps, Origin } from './base'; interface CanvasProps extends NodeProps { paint: ( @@ -15,9 +16,9 @@ export type CanvasNode = { type: typeof P.Canvas; props: CanvasProps; style?: Style | Style[]; - box?: never; + box?: Box; origin?: Origin; - yogaNode?: never; + yogaNode?: YogaNode; children?: never[]; }; diff --git a/packages/layout/src/types/circle.ts b/packages/layout/src/types/circle.ts index d445fd62c..eb6b5e863 100644 --- a/packages/layout/src/types/circle.ts +++ b/packages/layout/src/types/circle.ts @@ -1,7 +1,11 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { Origin, SVGPresentationAttributes } from './base'; +import { + Origin, + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; interface CircleProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; @@ -10,6 +14,13 @@ interface CircleProps extends SVGPresentationAttributes { r: string | number; } +interface SafeCircleProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + cx?: number; + cy?: number; + r: number; +} + export type CircleNode = { type: typeof P.Circle; props: CircleProps; @@ -20,6 +31,7 @@ export type CircleNode = { children?: never[]; }; -export type SafeCircleNode = Omit & { +export type SafeCircleNode = Omit & { style: SafeStyle; + props: SafeCircleProps; }; diff --git a/packages/layout/src/types/ellipse.ts b/packages/layout/src/types/ellipse.ts index a5962d957..fcecb7336 100644 --- a/packages/layout/src/types/ellipse.ts +++ b/packages/layout/src/types/ellipse.ts @@ -1,7 +1,10 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { SVGPresentationAttributes } from './base'; +import { + SafeSVGPresentationAttributes, + SVGPresentationAttributes, +} from './base'; interface EllipseProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; @@ -11,6 +14,14 @@ interface EllipseProps extends SVGPresentationAttributes { ry: string | number; } +interface SafeEllipseProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + cx?: number; + cy?: number; + rx: number; + ry: number; +} + export type EllipseNode = { type: typeof P.Ellipse; props: EllipseProps; @@ -21,6 +32,7 @@ export type EllipseNode = { children?: never[]; }; -export type SafeEllipseNode = Omit & { +export type SafeEllipseNode = Omit & { style: SafeStyle; + props: SafeEllipseProps; }; diff --git a/packages/layout/src/types/g.ts b/packages/layout/src/types/g.ts index d09389384..acce11c11 100644 --- a/packages/layout/src/types/g.ts +++ b/packages/layout/src/types/g.ts @@ -1,7 +1,6 @@ import { SafeStyle, Style } from '@react-pdf/stylesheet'; import * as P from '@react-pdf/primitives'; -import { SVGPresentationAttributes } from './base'; import { LineNode, SafeLineNode } from './line'; import { PolylineNode, SafePolylineNode } from './polyline'; import { PolygonNode, SafePolygonNode } from './polygon'; @@ -10,11 +9,21 @@ import { RectNode, SafeRectNode } from './rect'; import { CircleNode, SafeCircleNode } from './circle'; import { EllipseNode, SafeEllipseNode } from './ellipse'; import { SafeTspanNode, TspanNode } from './tspan'; +import { ImageNode, SafeImageNode } from './image'; +import { SafeTextNode, TextNode } from './text'; +import { + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; interface GProps extends SVGPresentationAttributes { style?: Style | Style[]; } +interface SafeGProps extends SafeSVGPresentationAttributes { + style?: Style; +} + export type GNode = { type: typeof P.G; props: GProps; @@ -30,13 +39,16 @@ export type GNode = { | RectNode | CircleNode | EllipseNode + | ImageNode + | TextNode | TspanNode | GNode )[]; }; -export type SafeGNode = Omit & { +export type SafeGNode = Omit & { style: SafeStyle; + props: SafeGProps; children?: ( | SafeLineNode | SafePolylineNode @@ -45,6 +57,8 @@ export type SafeGNode = Omit & { | SafeRectNode | SafeCircleNode | SafeEllipseNode + | SafeImageNode + | SafeTextNode | SafeTspanNode | SafeGNode )[]; diff --git a/packages/layout/src/types/image.ts b/packages/layout/src/types/image.ts index b5bfa4d15..84e20cedb 100644 --- a/packages/layout/src/types/image.ts +++ b/packages/layout/src/types/image.ts @@ -45,14 +45,18 @@ export type SourceObject = interface BaseImageProps extends NodeProps { cache?: boolean; + x?: number; + y?: number; } interface ImageWithSrcProp extends BaseImageProps { src: SourceObject; + source: never; } interface ImageWithSourceProp extends BaseImageProps { source: SourceObject; + src: never; } export type ImageProps = ImageWithSrcProp | ImageWithSourceProp; diff --git a/packages/layout/src/types/index.ts b/packages/layout/src/types/index.ts index aef8c25f2..1edce6cc9 100644 --- a/packages/layout/src/types/index.ts +++ b/packages/layout/src/types/index.ts @@ -1,5 +1,7 @@ export * from './base'; +export * from './canvas'; export * from './circle'; +export * from './checkbox'; export * from './clip-path'; export * from './defs'; export * from './document'; diff --git a/packages/layout/src/types/line.ts b/packages/layout/src/types/line.ts index 03f1221ef..7e571648f 100644 --- a/packages/layout/src/types/line.ts +++ b/packages/layout/src/types/line.ts @@ -1,7 +1,10 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { SVGPresentationAttributes } from './base'; +import { + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; interface LineProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; @@ -11,6 +14,14 @@ interface LineProps extends SVGPresentationAttributes { y2: string | number; } +interface SafeLineProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + x1: number; + x2: number; + y1: number; + y2: number; +} + export type LineNode = { type: typeof P.Line; props: LineProps; @@ -21,6 +32,7 @@ export type LineNode = { children?: never[]; }; -export type SafeLineNode = Omit & { +export type SafeLineNode = Omit & { style: SafeStyle; + props: SafeLineProps; }; diff --git a/packages/layout/src/types/linear-gradient.ts b/packages/layout/src/types/linear-gradient.ts index 1507e2ce6..793af7760 100644 --- a/packages/layout/src/types/linear-gradient.ts +++ b/packages/layout/src/types/linear-gradient.ts @@ -10,6 +10,14 @@ interface LinearGradientProps { y2?: string | number; } +interface SafeLinearGradientProps { + id: string; + x1?: number; + x2?: number; + y1?: number; + y2?: number; +} + export type LinearGradientNode = { type: typeof P.LinearGradient; props: LinearGradientProps; @@ -20,6 +28,10 @@ export type LinearGradientNode = { children?: StopNode[]; }; -export type SafeLinearGradientNode = Omit & { +export type SafeLinearGradientNode = Omit< + LinearGradientNode, + 'props' | 'children' +> & { + props: SafeLinearGradientProps; children?: SafeStopNode[]; }; diff --git a/packages/layout/src/types/path.ts b/packages/layout/src/types/path.ts index a74e69c78..8d5742327 100644 --- a/packages/layout/src/types/path.ts +++ b/packages/layout/src/types/path.ts @@ -1,13 +1,21 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { SVGPresentationAttributes } from './base'; +import { + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; interface PathProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; d: string; } +interface SafePathProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + d: string; +} + export type PathNode = { type: typeof P.Path; props: PathProps; @@ -18,6 +26,7 @@ export type PathNode = { children?: never[]; }; -export type SafePathNode = Omit & { +export type SafePathNode = Omit & { style: SafeStyle; + props: SafePathProps; }; diff --git a/packages/layout/src/types/polygon.ts b/packages/layout/src/types/polygon.ts index 23d07366a..9f919c493 100644 --- a/packages/layout/src/types/polygon.ts +++ b/packages/layout/src/types/polygon.ts @@ -1,13 +1,21 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { SVGPresentationAttributes } from './base'; +import { + SafeSVGPresentationAttributes, + SVGPresentationAttributes, +} from './base'; interface PolygonProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; points: string; } +interface SafePolygonProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + points: string; +} + export type PolygonNode = { type: typeof P.Polygon; props: PolygonProps; @@ -18,6 +26,7 @@ export type PolygonNode = { children?: never[]; }; -export type SafePolygonNode = Omit & { +export type SafePolygonNode = Omit & { style: SafeStyle; + props: SafePolygonProps; }; diff --git a/packages/layout/src/types/polyline.ts b/packages/layout/src/types/polyline.ts index b40198637..f303f1f54 100644 --- a/packages/layout/src/types/polyline.ts +++ b/packages/layout/src/types/polyline.ts @@ -1,13 +1,21 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { SVGPresentationAttributes } from './base'; +import { + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; interface PolylineProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; points: string; } +interface SafePolylineProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + points: string; +} + export type PolylineNode = { type: typeof P.Polyline; props: PolylineProps; @@ -18,6 +26,7 @@ export type PolylineNode = { children?: never[]; }; -export type SafePolylineNode = Omit & { +export type SafePolylineNode = Omit & { style: SafeStyle; + props: SafePolylineProps; }; diff --git a/packages/layout/src/types/radial-gradient.ts b/packages/layout/src/types/radial-gradient.ts index 2c1ae4937..30298d4d5 100644 --- a/packages/layout/src/types/radial-gradient.ts +++ b/packages/layout/src/types/radial-gradient.ts @@ -9,6 +9,17 @@ interface RadialGradientProps { fr?: string | number; fx?: string | number; fy?: string | number; + r?: string | number; +} + +interface SafeRadialGradientProps { + id: string; + cx?: number; + cy?: number; + fr?: number; + fx?: number; + fy?: number; + r?: number; } export type RadialGradientNode = { @@ -21,6 +32,10 @@ export type RadialGradientNode = { children?: StopNode[]; }; -export type SafeRadialGradientNode = Omit & { +export type SafeRadialGradientNode = Omit< + RadialGradientNode, + 'props' | 'children' +> & { + props: SafeRadialGradientProps; children?: SafeStopNode[]; }; diff --git a/packages/layout/src/types/rect.ts b/packages/layout/src/types/rect.ts index 84fa5b890..f8a18285b 100644 --- a/packages/layout/src/types/rect.ts +++ b/packages/layout/src/types/rect.ts @@ -1,7 +1,10 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; -import { SVGPresentationAttributes } from './base'; +import { + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; interface RectProps extends SVGPresentationAttributes { style?: SVGPresentationAttributes; @@ -13,6 +16,16 @@ interface RectProps extends SVGPresentationAttributes { ry?: string | number; } +interface SafeRectProps extends SafeSVGPresentationAttributes { + style?: SafeSVGPresentationAttributes; + x?: number; + y?: number; + width: number; + height: number; + rx?: number; + ry?: number; +} + export type RectNode = { type: typeof P.Rect; props: RectProps; @@ -23,6 +36,7 @@ export type RectNode = { children?: never[]; }; -export type SafeRectNode = Omit & { +export type SafeRectNode = Omit & { style: SafeStyle; + props: SafeRectProps; }; diff --git a/packages/layout/src/types/stop.ts b/packages/layout/src/types/stop.ts index e0889c135..cd5a2a77e 100644 --- a/packages/layout/src/types/stop.ts +++ b/packages/layout/src/types/stop.ts @@ -6,6 +6,12 @@ interface StopProps { stopOpacity?: string | number; } +interface StopSafeProps { + offset: number; + stopColor: string; + stopOpacity?: number; +} + export type StopNode = { type: typeof P.Stop; props: StopProps; @@ -16,4 +22,6 @@ export type StopNode = { children?: never[]; }; -export type SafeStopNode = StopNode; +export type SafeStopNode = Omit & { + props: StopSafeProps; +}; diff --git a/packages/layout/src/types/svg.ts b/packages/layout/src/types/svg.ts index 26306787e..acbcd1ea1 100644 --- a/packages/layout/src/types/svg.ts +++ b/packages/layout/src/types/svg.ts @@ -2,7 +2,13 @@ import { SafeStyle, Style } from '@react-pdf/stylesheet'; import * as P from '@react-pdf/primitives'; import { YogaNode } from 'yoga-layout/load'; -import { Box, NodeProps, Origin, SVGPresentationAttributes } from './base'; +import { + Box, + Origin, + NodeProps, + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; import { LineNode, SafeLineNode } from './line'; import { PolylineNode, SafePolylineNode } from './polyline'; import { PolygonNode, SafePolygonNode } from './polygon'; @@ -13,6 +19,8 @@ import { EllipseNode, SafeEllipseNode } from './ellipse'; import { SafeTspanNode, TspanNode } from './tspan'; import { GNode, SafeGNode } from './g'; import { DefsNode, SafeDefsNode } from './defs'; +import { SafeTextNode, TextNode } from './text'; +import { ImageNode, SafeImageNode } from './image'; export type Viewbox = { minX: number; @@ -40,7 +48,14 @@ interface SvgProps extends NodeProps, SVGPresentationAttributes { width?: string | number; height?: string | number; viewBox?: string | Viewbox; - preserveAspectRatio?: string | PreserveAspectRatio; + preserveAspectRatio?: string; +} + +interface SvgSafeProps extends NodeProps, SafeSVGPresentationAttributes { + width?: string | number; + height?: string | number; + viewBox?: Viewbox; + preserveAspectRatio?: PreserveAspectRatio; } export type SvgNode = { @@ -58,14 +73,17 @@ export type SvgNode = { | RectNode | CircleNode | EllipseNode + | ImageNode + | TextNode | TspanNode | GNode | DefsNode )[]; }; -export type SafeSvgNode = Omit & { +export type SafeSvgNode = Omit & { style: SafeStyle; + props: SvgSafeProps; children?: ( | SafeLineNode | SafePolylineNode @@ -74,6 +92,8 @@ export type SafeSvgNode = Omit & { | SafeRectNode | SafeCircleNode | SafeEllipseNode + | SafeImageNode + | SafeTextNode | SafeTspanNode | SafeGNode | SafeDefsNode diff --git a/packages/layout/src/types/tspan.ts b/packages/layout/src/types/tspan.ts index 10b87b658..3ccf7f112 100644 --- a/packages/layout/src/types/tspan.ts +++ b/packages/layout/src/types/tspan.ts @@ -1,7 +1,11 @@ import * as P from '@react-pdf/primitives'; import { SafeStyle, Style } from '@react-pdf/stylesheet'; +import { Paragraph } from '@react-pdf/textkit'; -import { SVGPresentationAttributes } from './base'; +import { + SVGPresentationAttributes, + SafeSVGPresentationAttributes, +} from './base'; import { SafeTextInstanceNode, TextInstanceNode } from './text-instance'; interface TspanProps extends SVGPresentationAttributes { @@ -9,6 +13,11 @@ interface TspanProps extends SVGPresentationAttributes { y?: string | number; } +interface SafeTspanProps extends SafeSVGPresentationAttributes { + x?: number; + y?: number; +} + export type TspanNode = { type: typeof P.Tspan; props: TspanProps; @@ -16,10 +25,12 @@ export type TspanNode = { box?: never; origin?: never; yogaNode?: never; + lines?: Paragraph; children?: TextInstanceNode[]; }; -export type SafeTspanNode = Omit & { +export type SafeTspanNode = Omit & { style: SafeStyle; + props: SafeTspanProps; children?: SafeTextInstanceNode[]; };