mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-23 23:02:17 +10:00
refactor: ponytail audit
This commit is contained in:
@@ -44,4 +44,16 @@ describe("createResumePdfBlob", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("returns a rejected Promise when the renderer fails synchronously", async () => {
|
||||
rendererMock.pdf.mockImplementationOnce(() => {
|
||||
throw new Error("renderer failed");
|
||||
});
|
||||
const { createResumePdfBlob } = await import("./browser");
|
||||
|
||||
const promise = createResumePdfBlob({ data: sampleResumeData });
|
||||
|
||||
expect(promise).toBeInstanceOf(Promise);
|
||||
await expect(promise).rejects.toThrow("renderer failed");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ type CreateResumePdfBlobOptions = {
|
||||
resolveSectionTitle?: SectionTitleResolver | undefined;
|
||||
};
|
||||
|
||||
// biome-ignore lint/suspicious/useAwait: keep synchronous renderer errors on the public Promise rejection path.
|
||||
export const createResumePdfBlob = async ({
|
||||
data,
|
||||
template,
|
||||
|
||||
@@ -9,10 +9,14 @@ import { Document } from "#react-pdf-renderer";
|
||||
import { RenderProvider } from "./context";
|
||||
import { registerFonts, resumeContentContainsCJK, resumeContentScripts } from "./hooks/use-register-fonts";
|
||||
import { getTemplatePage } from "./templates";
|
||||
import { shouldShowResumeHeader } from "./templates/shared/cover-letter";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "./templates/shared/page-size";
|
||||
|
||||
export type TemplatePageProps = {
|
||||
page: LayoutPage;
|
||||
pageIndex: number;
|
||||
pageSize: ReturnType<typeof getTemplatePageSize>;
|
||||
pageMinHeightStyle: ReturnType<typeof getTemplatePageMinHeightStyle>;
|
||||
showHeader: boolean;
|
||||
};
|
||||
|
||||
export type TemplatePage = ComponentType<TemplatePageProps>;
|
||||
@@ -43,6 +47,9 @@ export const ResumeDocument = ({ data, template, renderOptions, resolveSectionTi
|
||||
// fallback (#2986); the cast carries that wider runtime value through
|
||||
// `ResumeData` without changing the public schema.
|
||||
const resumeData = useMemo(() => ({ ...data, metadata: { ...data.metadata, typography } }), [data, typography]);
|
||||
const pageSize = getTemplatePageSize(resumeData.metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(resumeData.metadata.page.format);
|
||||
const headerResumeData = renderOptions ? { ...resumeData, renderOptions } : resumeData;
|
||||
|
||||
return (
|
||||
<RenderProvider data={resumeData} resolveSectionTitle={resolveSectionTitle} renderOptions={renderOptions}>
|
||||
@@ -57,7 +64,13 @@ export const ResumeDocument = ({ data, template, renderOptions, resolveSectionTi
|
||||
language={resumeData.metadata.page.locale}
|
||||
>
|
||||
{resumeData.metadata.layout.pages.map((page, index) => (
|
||||
<TemplatePageComponent key={getLayoutPageKey(page, index)} page={page} pageIndex={index} />
|
||||
<TemplatePageComponent
|
||||
key={getLayoutPageKey(page, index)}
|
||||
page={page}
|
||||
pageSize={pageSize}
|
||||
pageMinHeightStyle={pageMinHeightStyle}
|
||||
showHeader={shouldShowResumeHeader(headerResumeData, index)}
|
||||
/>
|
||||
))}
|
||||
</Document>
|
||||
</RenderProvider>
|
||||
|
||||
@@ -106,17 +106,6 @@ const toFontWeight = (weight: number): FontWeight => {
|
||||
return "900";
|
||||
};
|
||||
|
||||
const collectFontRangeWeights = (ranges: FontWeightRange[]): number[] => {
|
||||
const weights = new Set<number>();
|
||||
|
||||
for (const range of ranges) {
|
||||
weights.add(range.lowest);
|
||||
weights.add(range.highest);
|
||||
}
|
||||
|
||||
return [...weights];
|
||||
};
|
||||
|
||||
// Resolves the user-stored family to the one we hand to Font.register:
|
||||
// direct match → legacy alias (#2989) → IBM Plex Serif fallback.
|
||||
const resolvePdfFontFamily = (family: string) => {
|
||||
@@ -277,7 +266,7 @@ export const registerFonts = (
|
||||
const headingFallbacks = getPdfFallbackFontFamilies(headingFontFamily, { locale, scripts: fallbackScripts });
|
||||
|
||||
const registerFallbacks = (families: string[], ranges: FontWeightRange[]) => {
|
||||
const weights = collectFontRangeWeights(ranges);
|
||||
const weights = new Set(ranges.flatMap(({ lowest, highest }) => [lowest, highest]));
|
||||
|
||||
for (const family of families) {
|
||||
for (const weight of weights) {
|
||||
|
||||
@@ -20,10 +20,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -58,14 +56,11 @@ const azurillFeatures = {
|
||||
sectionTimeline: true,
|
||||
} satisfies TemplateFeatures;
|
||||
|
||||
export const AzurillPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const AzurillPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles, featureStyles } = useAzurillTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
|
||||
@@ -139,22 +134,17 @@ const useAzurillTemplate = (): AzurillTemplate => {
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
...base.page,
|
||||
flexDirection: "column",
|
||||
rowGap: metrics.headerGap,
|
||||
columnGap: metrics.columnGap,
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
sectionHeading: {
|
||||
color: primary,
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -70,14 +68,11 @@ const getBronzorSections = ({
|
||||
return sections;
|
||||
};
|
||||
|
||||
export const BronzorPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const BronzorPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { styles, colors } = useBronzorTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sections = getBronzorSections({ mainSections, sidebarSections, fullWidth: page.fullWidth });
|
||||
@@ -136,22 +131,17 @@ const useBronzorTemplate = (): BronzorTemplate => {
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
heading: { ...base.heading, fontWeight: metadata.typography.heading.fontWeights[0] ?? "500" },
|
||||
page: {
|
||||
...base.page,
|
||||
flexDirection: "column",
|
||||
rowGap: metrics.headerGap,
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: r.row,
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -47,15 +45,12 @@ type ChikoritaHeaderProps = {
|
||||
styles: ChikoritaStyles;
|
||||
};
|
||||
|
||||
export const ChikoritaPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const ChikoritaPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata, picture } = data;
|
||||
const { colors, styles } = useChikoritaTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const hasPicture = hasTemplatePicture(picture);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
|
||||
@@ -153,19 +148,14 @@ const useChikoritaTemplate = (): ChikoritaTemplate => {
|
||||
};
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
inline: { ...base.inline, columnGap: metrics.gapX(0.25) },
|
||||
page: {
|
||||
...base.page,
|
||||
flexDirection: r.row,
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -27,11 +27,23 @@ const readTemplate = (file: string) => {
|
||||
};
|
||||
|
||||
describe("cover letter PDF layout", () => {
|
||||
it.each(pageFiles)("%s suppresses the resume header for cover-letter-only documents", (file) => {
|
||||
it("derives shared page props in the document renderer", () => {
|
||||
const source = readTemplate("../document.tsx");
|
||||
|
||||
expect(source).toContain('from "./templates/shared/cover-letter"');
|
||||
expect(source).toContain('from "./templates/shared/page-size"');
|
||||
expect(source).toContain("showHeader={shouldShowResumeHeader");
|
||||
expect(source).toContain("pageSize={pageSize}");
|
||||
expect(source).toContain("pageMinHeightStyle={pageMinHeightStyle}");
|
||||
});
|
||||
|
||||
it.each(pageFiles)("%s renders the shared page props", (file) => {
|
||||
const source = readTemplate(file);
|
||||
|
||||
expect(source, basename(file)).toContain('from "../shared/cover-letter"');
|
||||
expect(source, basename(file)).toContain("shouldShowResumeHeader(data, pageIndex)");
|
||||
expect(source, basename(file)).not.toContain("const showHeader = pageIndex === 0;");
|
||||
expect(source, basename(file)).toContain("pageSize, pageMinHeightStyle, showHeader");
|
||||
expect(source, basename(file)).toContain("<Page size={pageSize}");
|
||||
expect(source, basename(file)).toContain("showHeader &&");
|
||||
expect(source, basename(file)).not.toContain('from "../shared/cover-letter"');
|
||||
expect(source, basename(file)).not.toContain('from "../shared/page-size"');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,11 +15,9 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { getFeaturedSummaryLayout } from "../shared/featured-summary";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -58,14 +56,11 @@ const ditgarFeatures = {
|
||||
mainItemHeaderBorder: true,
|
||||
} satisfies TemplateFeatures;
|
||||
|
||||
export const DitgarPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const DitgarPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useDitgarTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const showSidebar = !page.fullWidth || showHeader;
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
@@ -189,18 +184,13 @@ const useDitgarTemplate = (): DitgarTemplate => {
|
||||
};
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
...base.page,
|
||||
flexDirection: r.row,
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -52,15 +50,12 @@ type DittoHeaderProps = {
|
||||
styles: DittoStyles;
|
||||
};
|
||||
|
||||
export const DittoPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const DittoPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata, picture } = data;
|
||||
const { colors, styles } = useDittoTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const hasPicture = hasTemplatePicture(picture);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
|
||||
@@ -149,7 +144,7 @@ const useDittoTemplate = (): DittoTemplate => {
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const hasPicture = hasTemplatePicture(picture);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
@@ -161,13 +156,8 @@ const useDittoTemplate = (): DittoTemplate => {
|
||||
marginLeft: -picture.size / 2,
|
||||
},
|
||||
page: {
|
||||
...base.page,
|
||||
flexDirection: "column",
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -15,11 +15,9 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { getFeaturedSummaryLayout } from "../shared/featured-summary";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -53,14 +51,11 @@ type GengarHeaderProps = {
|
||||
colors: TemplateColorRoles;
|
||||
};
|
||||
|
||||
export const GengarPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const GengarPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useGengarTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const showSidebar = !page.fullWidth || showHeader;
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
@@ -185,18 +180,13 @@ const useGengarTemplate = (): GengarTemplate => {
|
||||
};
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
...base.page,
|
||||
flexDirection: r.row,
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -15,10 +15,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -55,14 +53,11 @@ const glalieFeatures = {
|
||||
stackSidebarItemHeader: true,
|
||||
} satisfies TemplateFeatures;
|
||||
|
||||
export const GlaliePage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const GlaliePage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useGlalieTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const showSidebar = !page.fullWidth || showHeader;
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
@@ -150,18 +145,10 @@ const useGlalieTemplate = (): GlalieTemplate => {
|
||||
};
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
rowGap: metrics.gapY(0.25),
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -46,14 +44,11 @@ type KakunaHeaderProps = {
|
||||
styles: KakunaStyles;
|
||||
};
|
||||
|
||||
export const KakunaPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const KakunaPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useKakunaTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
|
||||
@@ -119,20 +114,15 @@ const useKakunaTemplate = (): KakunaTemplate => {
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
rowGap: metrics.sectionGap,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -45,14 +43,11 @@ type LaprasHeaderProps = {
|
||||
styles: LaprasStyles;
|
||||
};
|
||||
|
||||
export const LaprasPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const LaprasPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useLaprasTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
|
||||
@@ -121,20 +116,15 @@ const useLaprasTemplate = (): LaprasTemplate => {
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
rowGap: metrics.gapY(1.5),
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -15,10 +15,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -51,14 +49,11 @@ type LeafishHeaderProps = {
|
||||
styles: LeafishStyles;
|
||||
};
|
||||
|
||||
export const LeafishPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const LeafishPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useLeafishTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data).filter((section) => section !== "summary");
|
||||
const sidebarSections = filterSections(page.sidebar, data).filter((section) => section !== "summary");
|
||||
|
||||
@@ -141,18 +136,10 @@ const useLeafishTemplate = (): LeafishTemplate => {
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
rowGap: metrics.gapY(0.25),
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -50,14 +48,11 @@ const meowthFeatures = {
|
||||
inlineItemHeader: true,
|
||||
} satisfies TemplateFeatures;
|
||||
|
||||
export const MeowthPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const MeowthPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useMeowthTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
|
||||
@@ -122,20 +117,15 @@ const useMeowthTemplate = (): MeowthTemplate => {
|
||||
const primary = rgbaStringToHex(metadata.design.colors.primary);
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
rowGap: metrics.sectionGap,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
inlineItemHeader: {
|
||||
flexDirection: r.row,
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -45,14 +43,11 @@ type OnyxHeaderProps = {
|
||||
styles: OnyxStyles;
|
||||
};
|
||||
|
||||
export const OnyxPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const OnyxPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useOnyxTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
|
||||
@@ -117,20 +112,15 @@ const useOnyxTemplate = (): OnyxTemplate => {
|
||||
const primary = rgbaStringToHex(metadata.design.colors.primary);
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
rowGap: metrics.sectionGap,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -55,14 +53,11 @@ const pikachuFeatures = {
|
||||
stackSidebarItemHeader: true,
|
||||
} satisfies TemplateFeatures;
|
||||
|
||||
export const PikachuPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const PikachuPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata, picture } = data;
|
||||
const { colors, styles } = usePikachuTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const showSidebar = !page.fullWidth;
|
||||
const hasPicture = hasTemplatePicture(picture);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
@@ -171,19 +166,14 @@ const usePikachuTemplate = (): PikachuTemplate => {
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -15,10 +15,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -48,14 +46,11 @@ type RhyhornHeaderProps = {
|
||||
styles: RhyhornStyles;
|
||||
};
|
||||
|
||||
export const RhyhornPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const RhyhornPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useRhyhornTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = filterSections(page.sidebar, data);
|
||||
|
||||
@@ -163,20 +158,15 @@ const useRhyhornTemplate = (): RhyhornTemplate => {
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const contactGap = metrics.gapX(0.5);
|
||||
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
rowGap: metrics.sectionGap,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
section: {
|
||||
flexDirection: "column",
|
||||
|
||||
@@ -14,10 +14,8 @@ import {
|
||||
WebsiteContactItem,
|
||||
} from "../shared/contact-item";
|
||||
import { TemplateProvider } from "../shared/context";
|
||||
import { shouldShowResumeHeader } from "../shared/cover-letter";
|
||||
import { filterSections } from "../shared/filtering";
|
||||
import { getTemplateMetrics } from "../shared/metrics";
|
||||
import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "../shared/page-size";
|
||||
import { hasTemplatePicture } from "../shared/picture";
|
||||
import { Heading, Text } from "../shared/primitives";
|
||||
import { createRtlStyleHelpers } from "../shared/rtl";
|
||||
@@ -46,14 +44,11 @@ type ScizorHeaderProps = {
|
||||
styles: ScizorStyles;
|
||||
};
|
||||
|
||||
export const ScizorPage = ({ page, pageIndex }: TemplatePageProps) => {
|
||||
export const ScizorPage = ({ page, pageSize, pageMinHeightStyle, showHeader }: TemplatePageProps) => {
|
||||
const data = useRender();
|
||||
const { metadata } = data;
|
||||
const { colors, styles } = useScizorTemplate();
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const pageSize = getTemplatePageSize(metadata.page.format);
|
||||
const pageMinHeightStyle = getTemplatePageMinHeightStyle(metadata.page.format);
|
||||
const showHeader = shouldShowResumeHeader(data, pageIndex);
|
||||
const mainSections = filterSections(page.main, data);
|
||||
const sidebarSections = page.fullWidth ? [] : filterSections(page.sidebar, data);
|
||||
const sections = [...mainSections, ...sidebarSections];
|
||||
@@ -111,22 +106,17 @@ const useScizorTemplate = (): ScizorTemplate => {
|
||||
const divider = "#D8DCE2";
|
||||
const colors: TemplateColorRoles = { foreground, background, primary };
|
||||
const metrics = getTemplateMetrics(metadata.page);
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, r, metrics, picture });
|
||||
const base = createBaseTemplateStyles({ metadata, foreground, background, r, metrics, picture });
|
||||
|
||||
const baseStyles = StyleSheet.create({
|
||||
...base,
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
...base.page,
|
||||
borderTopWidth: metrics.gapY(0.45),
|
||||
borderTopColor: primary,
|
||||
paddingHorizontal: metrics.page.paddingHorizontal,
|
||||
paddingVertical: metrics.page.paddingVertical,
|
||||
rowGap: metrics.sectionGap,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
},
|
||||
heading: { ...base.heading, fontWeight: metadata.typography.heading.fontWeights.at(-1) ?? "700" },
|
||||
bold: { fontWeight: metadata.typography.body.fontWeights.at(-1) ?? "700", color: foreground },
|
||||
|
||||
@@ -7,6 +7,7 @@ import { rgbaStringToHex } from "@reactive-resume/utils/color";
|
||||
type BaseTemplateStylesInput = {
|
||||
metadata: ResumeData["metadata"];
|
||||
foreground: string;
|
||||
background: string;
|
||||
r: ReturnType<typeof createRtlStyleHelpers>;
|
||||
metrics: ReturnType<typeof getTemplateMetrics>;
|
||||
picture: Picture;
|
||||
@@ -20,7 +21,14 @@ type BaseTemplateStylesInput = {
|
||||
* ponytail: factory returns plain objects, not StyleSheet.create'd; each template does one
|
||||
* StyleSheet.create pass so the final resolved styles are identical to before.
|
||||
*/
|
||||
export function createBaseTemplateStyles({ metadata, foreground, r, metrics, picture }: BaseTemplateStylesInput) {
|
||||
export function createBaseTemplateStyles({
|
||||
metadata,
|
||||
foreground,
|
||||
background,
|
||||
r,
|
||||
metrics,
|
||||
picture,
|
||||
}: BaseTemplateStylesInput) {
|
||||
const bodyText = {
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
@@ -31,6 +39,15 @@ export function createBaseTemplateStyles({ metadata, foreground, r, metrics, pic
|
||||
} satisfies Style;
|
||||
|
||||
return {
|
||||
page: {
|
||||
color: foreground,
|
||||
backgroundColor: background,
|
||||
fontFamily: metadata.typography.body.fontFamily,
|
||||
fontSize: metadata.typography.body.fontSize,
|
||||
lineHeight: metadata.typography.body.lineHeight,
|
||||
direction: r.pageDirection,
|
||||
} satisfies Style,
|
||||
|
||||
/** The canonical body text style; alias for `text` in StyleSheet slots. */
|
||||
text: bodyText,
|
||||
|
||||
|
||||
@@ -14,6 +14,14 @@ describe("ExperienceSection", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("ItemTitle", () => {
|
||||
it("renders award titles without the bold style", () => {
|
||||
expect(source).toContain("const ItemTitle = ({ children, website, bold = true }: ItemTitleProps)");
|
||||
expect(source).toContain("const title = bold ? <Bold>{children}</Bold> : <Text>{children}</Text>;");
|
||||
expect(source).toContain("<ItemTitle website={item.website} bold={false}>");
|
||||
});
|
||||
});
|
||||
|
||||
describe("SectionShell", () => {
|
||||
it("keeps section and heading style rules when section heading icons are hidden", () => {
|
||||
expect(source).toContain("<View style={composeStyles(sectionStyle, sectionRuleStyle)} {...breakProps}>");
|
||||
|
||||
@@ -90,6 +90,7 @@ type ItemWebsite = {
|
||||
type ItemTitleProps = {
|
||||
children: ReactNode;
|
||||
website: ItemWebsite;
|
||||
bold?: boolean;
|
||||
};
|
||||
|
||||
type ItemWebsiteLinkProps = {
|
||||
@@ -383,9 +384,9 @@ const SectionItemHeader = ({ children }: SectionItemHeaderProps) => {
|
||||
return <View style={composeStyles(sectionItemHeaderStyle)}>{children}</View>;
|
||||
};
|
||||
|
||||
const ItemTitle = ({ children, website }: ItemTitleProps) => {
|
||||
const ItemTitle = ({ children, website, bold = true }: ItemTitleProps) => {
|
||||
const inlineWebsiteUrl = getInlineItemWebsiteUrl(website);
|
||||
const title = <Bold>{children}</Bold>;
|
||||
const title = bold ? <Bold>{children}</Bold> : <Text>{children}</Text>;
|
||||
|
||||
if (!inlineWebsiteUrl) return title;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user