diff --git a/apps/web/src/components/input/rich-input.tsx b/apps/web/src/components/input/rich-input.tsx
index 37b9caa93..2973cce2c 100644
--- a/apps/web/src/components/input/rich-input.tsx
+++ b/apps/web/src/components/input/rich-input.tsx
@@ -121,8 +121,7 @@ export function RichInput({ value, onChange, style, className, editorClassName,
"data-editor": "true",
"data-fullscreen": isFullscreen ? "true" : "false",
class: cn(
- "group/editor overflow-y-auto p-3 pb-4",
- "prose prose-sm prose-zinc dark:prose-invert max-w-none",
+ "wysiwyg group/editor overflow-y-auto p-3 pb-4",
"rounded-md rounded-t-none border outline-none focus-visible:border-ring",
"[td:has(.selectedCell)]:bg-primary",
"data-[fullscreen=false]:max-h-[400px] data-[fullscreen=false]:min-h-[100px]",
diff --git a/packages/pdf/src/templates/shared/section-links.test.ts b/packages/pdf/src/templates/shared/section-links.test.ts
new file mode 100644
index 000000000..6904ff418
--- /dev/null
+++ b/packages/pdf/src/templates/shared/section-links.test.ts
@@ -0,0 +1,37 @@
+import { describe, expect, test } from "vitest";
+import { getInlineItemWebsiteUrl, shouldRenderSeparateItemWebsite } from "./section-links";
+
+describe("section item website links", () => {
+ test("uses inline website URL and suppresses the separate website link when inlineLink is true", () => {
+ const website = {
+ url: "https://example.com/company",
+ label: "example.com/company",
+ inlineLink: true,
+ };
+
+ expect(getInlineItemWebsiteUrl(website)).toBe("https://example.com/company");
+ expect(shouldRenderSeparateItemWebsite(website)).toBe(false);
+ });
+
+ test("renders the website separately when inlineLink is false", () => {
+ const website = {
+ url: "https://example.com/company",
+ label: "example.com/company",
+ inlineLink: false,
+ };
+
+ expect(getInlineItemWebsiteUrl(website)).toBeUndefined();
+ expect(shouldRenderSeparateItemWebsite(website)).toBe(true);
+ });
+
+ test("does not create an inline or separate link without a URL", () => {
+ const website = {
+ url: "",
+ label: "",
+ inlineLink: true,
+ };
+
+ expect(getInlineItemWebsiteUrl(website)).toBeUndefined();
+ expect(shouldRenderSeparateItemWebsite(website)).toBe(false);
+ });
+});
diff --git a/packages/pdf/src/templates/shared/section-links.ts b/packages/pdf/src/templates/shared/section-links.ts
new file mode 100644
index 000000000..10b525012
--- /dev/null
+++ b/packages/pdf/src/templates/shared/section-links.ts
@@ -0,0 +1,15 @@
+import type { Website } from "@reactive-resume/schema/resume/data";
+
+type ItemWebsite = Website & {
+ inlineLink?: boolean | undefined;
+};
+
+export const getInlineItemWebsiteUrl = (website: ItemWebsite): string | undefined => {
+ if (!website.url || !website.inlineLink) return undefined;
+
+ return website.url;
+};
+
+export const shouldRenderSeparateItemWebsite = (website: ItemWebsite): boolean => {
+ return Boolean(website.url && !website.inlineLink);
+};
diff --git a/packages/pdf/src/templates/shared/sections.tsx b/packages/pdf/src/templates/shared/sections.tsx
index 5ab5de66a..e6cc889da 100644
--- a/packages/pdf/src/templates/shared/sections.tsx
+++ b/packages/pdf/src/templates/shared/sections.tsx
@@ -38,6 +38,7 @@ import { MetaLine } from "./meta-line";
import { getTemplateMetrics } from "./metrics";
import { Bold, Div, Heading, Icon, Link, Small, Text } from "./primitives";
import { RichText } from "./rich-text";
+import { getInlineItemWebsiteUrl, shouldRenderSeparateItemWebsite } from "./section-links";
import { composeStyles } from "./styles";
type SectionItemsContextValue = {
@@ -206,6 +207,27 @@ const SectionItemHeader = ({ children }: { children: ReactNode }) => {
return {children};
};
+type ItemWebsite = {
+ url: string;
+ label: string;
+ inlineLink?: boolean | undefined;
+};
+
+const ItemTitle = ({ children, website }: { children: ReactNode; website: ItemWebsite }) => {
+ const inlineWebsiteUrl = getInlineItemWebsiteUrl(website);
+ const title = {children};
+
+ if (!inlineWebsiteUrl) return title;
+
+ return {title};
+};
+
+const ItemWebsiteLink = ({ website }: { website: ItemWebsite }) => {
+ if (!shouldRenderSeparateItemWebsite(website)) return null;
+
+ return {website.label || website.url};
+};
+
const SummarySection = ({ showHeading = true }: { showHeading?: boolean } = {}) => {
const data = useRender();
const { summary } = data;
@@ -272,9 +294,7 @@ const ProfileSection = ({
{item.network}
-
- {item.username}
-
+ {item.username}
))}
@@ -316,7 +336,7 @@ const ExperienceSection = ({
) : null
}
- middle={{item.company}}
+ middle={{item.company}}
trailing={{item.period}}
/>
);
@@ -324,7 +344,7 @@ const ExperienceSection = ({
const renderSplitHeader = () => (
<>
- {item.company}
+ {item.company}
{item.location}
@@ -355,11 +375,7 @@ const ExperienceSection = ({
{item.roles.length === 0 && {item.description}}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
);
})}
@@ -406,7 +422,7 @@ const EducationSection = ({
) : null
}
- middle={{item.school}}
+ middle={{item.school}}
trailing={{item.period}}
/>
{gradeAndLocation && {gradeAndLocation}}
@@ -416,7 +432,7 @@ const EducationSection = ({
const renderSplitHeader = () => (
<>
- {item.school}
+ {item.school}
{degreeAndGrade}
@@ -433,11 +449,7 @@ const EducationSection = ({
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
);
})}
@@ -468,18 +480,14 @@ const ProjectsSection = ({
- {item.name}
+ {item.name}
{item.period}
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
))}
@@ -610,17 +618,13 @@ const AwardsSection = ({
{items.map((item) => (
- {item.title}
+ {item.title}
{item.awarder}
{item.date}
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
))}
@@ -647,17 +651,13 @@ const CertificationsSection = ({
{items.map((item) => (
- {item.title}
+ {item.title}
{item.issuer}
{item.date}
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
))}
@@ -684,17 +684,13 @@ const PublicationsSection = ({
{items.map((item) => (
- {item.title}
+ {item.title}
{item.publisher}
{item.date}
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
))}
@@ -727,13 +723,13 @@ const VolunteerSection = ({
{inlineItemHeader ? (
{item.location}}
- middle={{item.organization}}
+ middle={{item.organization}}
trailing={{item.period}}
/>
) : (
<>
- {item.organization}
+ {item.organization}
{item.location}
@@ -743,11 +739,7 @@ const VolunteerSection = ({
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
))}
@@ -774,17 +766,13 @@ const ReferencesSection = ({
{items.map((item) => (
- {item.name}
+ {item.name}
{item.position}
{[item.phone]}
{item.description}
- {item.website.url && (
-
- {item.website.label || item.website.url}
-
- )}
+
))}
diff --git a/packages/ui/src/styles/globals.css b/packages/ui/src/styles/globals.css
index 3744ddafb..55c60daff 100644
--- a/packages/ui/src/styles/globals.css
+++ b/packages/ui/src/styles/globals.css
@@ -152,6 +152,10 @@
[role="button"]:not(:disabled) {
cursor: pointer;
}
+
+ .wysiwyg {
+ @apply prose prose-sm prose-zinc dark:prose-invert max-w-none prose-p:my-0! prose-li:my-0! prose-ul:my-0! prose-ol:my-0!;
+ }
}
@media (prefers-reduced-motion: reduce) {