Files
Reactive-Resume/packages/pdf/src/context.tsx
T
Amruth Pillai 098df60230 feat: choose which side the sidebar sits on
Two-column templates take a sidebarSide from the layout (left or right).
Without one, each template keeps its own side and right-to-left pages
mirror it. The PDF templates reverse only their columns, header band
and sidebar background, and the DOCX export follows the same choice.
Design's Sidebar panel offers Left and Right.
2026-09-29 08:00:33 +02:00

61 lines
2.1 KiB
TypeScript

import type { ResumeData } from "@reactive-resume/schema/resume/data";
import type { Template } from "@reactive-resume/schema/templates";
import type { ReactNode } from "react";
import type { SectionTitleResolver } from "./section-title";
import { createContext, use, useMemo } from "react";
import { templateLayouts } from "@reactive-resume/schema/templates";
import { isRTL } from "@reactive-resume/utils/locale";
export type ResumeRenderOptions = {
includeCoverLetterHeader?: boolean;
};
type RenderContextValue = ResumeData & {
resolveSectionTitle?: SectionTitleResolver | undefined;
renderOptions: ResumeRenderOptions;
rtl: boolean;
/**
* Whether a two-column template lays its columns out from the right: its sidebar goes to the other side from
* where the template draws it. That's the side chosen in Design, or, without a choice, a right-to-left page.
*/
columnsReversed: boolean;
};
const RenderContext = createContext<RenderContextValue | null>(null);
const defaultRenderOptions: ResumeRenderOptions = {};
type RenderProviderProps = {
data: ResumeData;
resolveSectionTitle?: SectionTitleResolver | undefined;
renderOptions?: ResumeRenderOptions | undefined;
template?: Template | undefined;
children: ReactNode;
};
export const RenderProvider = ({
data,
resolveSectionTitle,
renderOptions = defaultRenderOptions,
template,
children,
}: RenderProviderProps) => {
const rtl = isRTL(data.metadata.page.locale);
const chosenSide = data.metadata.layout.sidebarSide;
const ownSide = template ? templateLayouts[template].sidebarSide : null;
const columnsReversed = chosenSide && ownSide ? chosenSide !== ownSide : rtl;
const contextValue = useMemo<RenderContextValue>(
() => ({ ...data, resolveSectionTitle, renderOptions, rtl, columnsReversed }),
[data, resolveSectionTitle, renderOptions, rtl, columnsReversed],
);
return <RenderContext.Provider value={contextValue}>{children}</RenderContext.Provider>;
};
export const useRender = (): RenderContextValue => {
const context = use(RenderContext);
if (!context) throw new Error("useRender must be called inside a <RenderProvider>.");
return context;
};