mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-20 15:05:48 +10:00
feat: add section heading icons to PDF templates (#3127)
* feat: add section heading icons to PDF templates Add customizable Phosphor icons before section titles in PDF output. Users can toggle visibility globally via a new "Hide section heading icons" switch (independent of item-level icons) and customize individual section icons through the builder sidebar icon picker. - Add `icon` field to `baseSectionSchema` and `summarySchema` - Add `hideSectionIcons` to `pageSchema` (defaults to true for backward compat) - Implement `SectionHeadingIcon` component with heading font-size scaling - Support "none" sentinel for per-section icon hiding - Fallback to sensible defaults (briefcase, graduation-cap, etc.) for legacy data - Add icon picker to builder sidebar sections and custom section dialogs Closes #2632 * test: add unit tests for section heading icons - Add tests for getResumeSectionIcon() covering built-in sections, summary, custom sections, "none" sentinel, and default fallbacks - Add schema tests for baseSectionSchema icon field, summarySchema icon, and pageSchema hideSectionIcons default behavior * refactor: minor updates to icon display * Update apps/web/locales/es-ES.po Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: Amruth Pillai <im.amruth@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import type { CustomSection, ResumeData, SectionType } from "@reactive-resume/schema/resume/data";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getDefaultSectionIconName } from "@reactive-resume/schema/resume/section-icons";
|
||||
import { renderBuiltInSection, renderCustomSection, renderSummary, setRenderConfig } from "./section-renderers";
|
||||
|
||||
const baseConfig = {
|
||||
@@ -21,6 +22,7 @@ describe("renderSummary", () => {
|
||||
it("returns [] when the section is hidden", () => {
|
||||
const summary: ResumeData["summary"] = {
|
||||
title: "Summary",
|
||||
icon: getDefaultSectionIconName("summary"),
|
||||
content: "<p>Hello</p>",
|
||||
hidden: true,
|
||||
columns: 1,
|
||||
@@ -31,6 +33,7 @@ describe("renderSummary", () => {
|
||||
it("returns [] when content is empty", () => {
|
||||
const summary: ResumeData["summary"] = {
|
||||
title: "Summary",
|
||||
icon: getDefaultSectionIconName("summary"),
|
||||
content: "",
|
||||
hidden: false,
|
||||
columns: 1,
|
||||
@@ -41,6 +44,7 @@ describe("renderSummary", () => {
|
||||
it("includes a heading paragraph when both title and content are present", () => {
|
||||
const summary: ResumeData["summary"] = {
|
||||
title: "Summary",
|
||||
icon: getDefaultSectionIconName("summary"),
|
||||
content: "<p>Hello world</p>",
|
||||
hidden: false,
|
||||
columns: 1,
|
||||
@@ -53,6 +57,7 @@ describe("renderSummary", () => {
|
||||
it("omits the heading when title is empty but still renders content", () => {
|
||||
const summary: ResumeData["summary"] = {
|
||||
title: "",
|
||||
icon: getDefaultSectionIconName("summary"),
|
||||
content: "<p>Hello world</p>",
|
||||
hidden: false,
|
||||
columns: 1,
|
||||
@@ -62,9 +67,10 @@ describe("renderSummary", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const emptySection = <T extends SectionType>(_type: T): ResumeData["sections"][T] =>
|
||||
const emptySection = <T extends SectionType>(type: T): ResumeData["sections"][T] =>
|
||||
({
|
||||
title: "Section",
|
||||
icon: getDefaultSectionIconName(type),
|
||||
columns: 1,
|
||||
hidden: false,
|
||||
items: [],
|
||||
@@ -90,6 +96,7 @@ describe("renderCustomSection", () => {
|
||||
id: "custom-1",
|
||||
type: "summary",
|
||||
title: "Notes",
|
||||
icon: getDefaultSectionIconName("summary"),
|
||||
columns: 1,
|
||||
hidden: false,
|
||||
items: [],
|
||||
|
||||
Reference in New Issue
Block a user