mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-23 14:52:18 +10:00
refactor(stylesheet): move Semantic CSS to the browser (#3329)
This commit is contained in:
@@ -1,18 +1,42 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { z } from "zod";
|
||||
import { describe, expect, expectTypeOf, it } from "vitest";
|
||||
import { resumeDataSchema } from "./data";
|
||||
import { defaultResumeData } from "./default";
|
||||
import { semanticStylesheetSchema, stylesheetSourceSchema } from "./stylesheet";
|
||||
|
||||
describe("semanticStylesheetSchema", () => {
|
||||
it("preserves separate editable and applied sources", () => {
|
||||
it("keeps the public input canonical instead of widening it to unknown", () => {
|
||||
type StylesheetInput = z.input<typeof semanticStylesheetSchema>;
|
||||
type CanonicalInput = {
|
||||
mode: "legacy" | "semantic";
|
||||
source: { languageVersion: number; text: string };
|
||||
};
|
||||
|
||||
expectTypeOf<StylesheetInput>().toEqualTypeOf<CanonicalInput>();
|
||||
expectTypeOf<string>().not.toExtend<StylesheetInput>();
|
||||
});
|
||||
|
||||
it("persists one canonical stylesheet source", () => {
|
||||
const result = semanticStylesheetSchema.parse({
|
||||
mode: "semantic",
|
||||
source: { languageVersion: 1, text: "@version 1;\nsection {" },
|
||||
applied: { languageVersion: 1, text: "@version 1;\nsection { color: red; }\n" },
|
||||
source: { languageVersion: 1, text: "@version 1;\nsection { color: red; }\n" },
|
||||
});
|
||||
|
||||
expect(result.source.text).toContain("section {");
|
||||
expect(result.applied.text).toContain("color: red");
|
||||
expect(result).toEqual({
|
||||
mode: "semantic",
|
||||
source: { languageVersion: 1, text: "@version 1;\nsection { color: red; }\n" },
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes the historical applied source to the canonical source-only shape", () => {
|
||||
const source = { languageVersion: 1, text: "@version 1;\nname { color: red; }\n" };
|
||||
const result = semanticStylesheetSchema.parse({
|
||||
mode: "semantic",
|
||||
source,
|
||||
applied: { languageVersion: 1, text: "@version 1;\nname { color: blue; }\n" },
|
||||
});
|
||||
|
||||
expect(result).toEqual({ mode: "semantic", source });
|
||||
});
|
||||
|
||||
it("keeps resumes without a stylesheet valid for legacy rendering", () => {
|
||||
@@ -24,7 +48,6 @@ describe("semanticStylesheetSchema", () => {
|
||||
semanticStylesheetSchema.safeParse({
|
||||
mode: "semantic",
|
||||
source: { languageVersion: 0, text: "" },
|
||||
applied: { languageVersion: 1, text: "" },
|
||||
}).success,
|
||||
).toBe(false);
|
||||
});
|
||||
@@ -34,7 +57,6 @@ describe("semanticStylesheetSchema", () => {
|
||||
semanticStylesheetSchema.safeParse({
|
||||
mode: "semantic",
|
||||
source: { languageVersion: 1, text: "" },
|
||||
applied: { languageVersion: 1, text: "" },
|
||||
unknown: true,
|
||||
}).success,
|
||||
).toBe(false);
|
||||
|
||||
@@ -7,12 +7,30 @@ export const stylesheetSourceSchema = z.strictObject({
|
||||
text: z.string(),
|
||||
});
|
||||
|
||||
export const semanticStylesheetSchema = z.strictObject({
|
||||
const canonicalSemanticStylesheetSchema = z.strictObject({
|
||||
mode: z.enum(["legacy", "semantic"]),
|
||||
source: stylesheetSourceSchema,
|
||||
applied: stylesheetSourceSchema,
|
||||
});
|
||||
|
||||
type SemanticStylesheetInput = z.input<typeof canonicalSemanticStylesheetSchema>;
|
||||
|
||||
const normalizeHistoricalStylesheet = (input: unknown): unknown => {
|
||||
if (typeof input !== "object" || input === null || Array.isArray(input) || !Object.hasOwn(input, "applied")) {
|
||||
return input;
|
||||
}
|
||||
|
||||
const { applied, ...stylesheet } = input as Record<string, unknown>;
|
||||
return stylesheetSourceSchema.safeParse(applied).success ? stylesheet : input;
|
||||
};
|
||||
|
||||
const semanticStylesheetCompatibilityTransform = z.transform<SemanticStylesheetInput, SemanticStylesheetInput>(
|
||||
(input) => normalizeHistoricalStylesheet(input) as SemanticStylesheetInput,
|
||||
);
|
||||
|
||||
export const semanticStylesheetSchema = semanticStylesheetCompatibilityTransform.pipe(
|
||||
canonicalSemanticStylesheetSchema,
|
||||
);
|
||||
|
||||
export type StylesheetSource = z.infer<typeof stylesheetSourceSchema>;
|
||||
export type SemanticStylesheet = z.infer<typeof semanticStylesheetSchema>;
|
||||
export type StylesheetMode = SemanticStylesheet["mode"];
|
||||
|
||||
Reference in New Issue
Block a user