Skip to content

Commit

Permalink
Extract custom classes into a separate block
Browse files Browse the repository at this point in the history
This is done by checking the error repeatedly for custom classes and moving them to another array until no more error is presented.

Also: Refactor API code to simplify some constants and to remove unneeded parts like @tailwind directives and finding `.generated` text.
  • Loading branch information
ADTC committed Nov 2, 2024
1 parent 94023f2 commit 3c2a362
Showing 1 changed file with 59 additions and 42 deletions.
101 changes: 59 additions & 42 deletions pages/api/generate-css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import postcss from "postcss";
import postcss, { type CssSyntaxError } from "postcss";
import tailwindcss from "tailwindcss";
import autoprefixer from "autoprefixer";
import { NextApiRequest, NextApiResponse } from "next";
Expand All @@ -8,52 +8,69 @@ interface RequestBody {
classes: string;
}

const processor = postcss([
tailwindcss({
config: { content: ["./*.none"], corePlugins: { preflight: false } },
}),
autoprefixer,
]);

const beautifyOptions: Parameters<typeof cssbeautify>[1] = {
indent: " ",
openbrace: "end-of-line",
autosemicolon: true,
};

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const { classes }: RequestBody = req.body;

const css = `
@tailwind base;
@tailwind components;
@tailwind utilities;
.generated {
@apply ${classes};
}
`;

try {
const result = await postcss([
tailwindcss({
config: { content: ["./*.none"], corePlugins: { preflight: false } },
}),
autoprefixer,
])
.process(css, { from: undefined })
.then((result) => {
let css = result.css;

// Find ".generated" text and extract everything after it.
const generatedIndex = css.indexOf(".generated");
if (generatedIndex !== -1) {
css = css.substring(generatedIndex);
} else {
css = "no: result;";
}
const body: RequestBody = req.body;
const classes: string[] = body.classes.split(" ");
const customClasses: string[] = [];
let doneProcessing = false;

do {
try {
const css = `.generated { @apply ${classes.join(" ")}; }`;

let result = await processor
.process(css, { from: undefined })
.then((result) => result.css);

// Format the CSS using cssbeautify
css = cssbeautify(css, {
indent: " ",
openbrace: "end-of-line",
autosemicolon: true,
});
if (customClasses.length) {
const classes = customClasses.join(", .");
result = `.${classes} {\n /* Custom classes not found in Tailwind CSS */} ${result}`;
}

return css.trim();
});
result = cssbeautify(result, beautifyOptions);

res.status(200).send(result);
} catch (error) {
res.status(500).send(error.toString());
}
res.status(200).send(result);
doneProcessing = true;

//
} catch (error) {
if (error?.name === "CssSyntaxError") {
const cssError = error as CssSyntaxError;
const customClass = cssError.reason.match(
/`([^`]+)` class does not exist/
)?.[1];

if (customClass) {
customClasses.push(customClass);
classes.splice(classes.indexOf(customClass), 1);

//
} else {
res.status(500).send(error.toString());
doneProcessing = true;
}

//
} else {
res.status(500).send(error.toString());
doneProcessing = true;
}
}
} while (!doneProcessing);
}

0 comments on commit 3c2a362

Please sign in to comment.