Skip to content

Commit

Permalink
Add preflight check
Browse files Browse the repository at this point in the history
  • Loading branch information
dolanmiu committed Jan 10, 2024
1 parent bf3185b commit 86389ab
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 3 deletions.
21 changes: 21 additions & 0 deletions __mocks__/compiled-jsx.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Use https://babeljs.io/repl to make

export const COMPILED_JSX = `
import { Fragment, jsx } from "react/jsx-runtime";
import { useState } from "react";
Expand Down Expand Up @@ -25,3 +27,22 @@ const TestComponent = ({ isOpen, onClose, onDone }) => {
};
export { TestComponent };
`;

export const COMPILED_BACK_TICK_JSX_WITH_PREFLIGHT_TAGS = `
import { Fragment, jsx } from "react/jsx-runtime";
import { useState } from "react";
export const TestComponent = () => {
return /*#__PURE__*/_jsxs("div", {
children: [/*#__PURE__*/_jsx("h1", {
children: "Hello"
}), /*#__PURE__*/_jsx("h2", {
className: \`test \${variable}\`,
children: "World"
}), /*#__PURE__*/_jsx("h1", {
children: "Foo"
}), /*#__PURE__*/_jsx("h1", {
children: "Bar"
})]
});
};
`;
4 changes: 4 additions & 0 deletions __mocks__/html.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export const HTML = `
<div id="react-checkout-app" class="fixed top-40 h-[calc(100dvh-var(--spacing-5))] w-full rounded-4 bg-white md:w-[700px] md:px-32">
<h1>Hello</h1>
<h2 class="test">World</h2>
<h1>Foo</h1>
<h1>Bar</h1>
<header class="sticky top-0 z-10 flex items-center justify-between bg-white pr-[10px] md:pt-16 px-3.5">
<button class="nav before:back" tabindex="0"></button>
<button class="nav after:exit" tabindex="1">Test</button>
Expand Down
2 changes: 1 addition & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"ignoreRegExpList": [],
"ignorePaths": [".vscode", "dist", "coverage", ".gitignore"],
"allowCompoundWords": true,
"words": ["cobertura", "codecov", "Dolan", "uniqid"]
"words": ["cobertura", "codecov", "Dolan", "jsxs", "uniqid"]
}
30 changes: 30 additions & 0 deletions src/append-tags.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, it, expect } from "vitest";
import { appendTags, appendTagsForReact } from "./append-tags";
import { COMPILED_BACK_TICK_JSX_WITH_PREFLIGHT_TAGS } from "@/mocks/compiled-jsx";
import { HTML } from "@/mocks/html";

describe("append-tags", () => {
describe("appendTagsForReact", () => {
it("should work", async () => {
const transformedCode = appendTagsForReact("test-id")(
COMPILED_BACK_TICK_JSX_WITH_PREFLIGHT_TAGS,
);
expect(transformedCode).toEqual(
expect.objectContaining({
code: expect.stringContaining(`className: "test-id`),
}),
);
});
});

describe("appendTags", () => {
it("should work", async () => {
const transformedCode = appendTags("test-id")(HTML);
expect(transformedCode).toEqual(
expect.objectContaining({
code: expect.stringContaining(`class="test-id`),
}),
);
});
});
});
58 changes: 58 additions & 0 deletions src/append-tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { appendClass, appendClassForReact } from "./append-classes";
import { PREFLIGHT_AFFECTED_TAGS } from "./postcss/preflight";

export const appendTagsForReact = (id: string) => (code: string) => {
let currCode = code;
for (const tag of PREFLIGHT_AFFECTED_TAGS) {
const regex = new RegExp(`"${tag}", {(?:.|\\s)+?}\\)`, "g");
const matches = [...currCode.matchAll(regex)].map((m) => m[0]);

for (const match of matches) {
const output = appendClassForReact(id)(match);

if (output.code === match) {
// That means that className is not present
// We need to add it
currCode = currCode.replace(
match,
match.replace(`, {`, `, {\nclassName: "${id}",`),
);
} else {
currCode = currCode.replace(match, output.code);
}
}
}

return {
code: currCode,
map: null,
};
};

export const appendTags = (id: string) => (code: string) => {
let currCode = code;
for (const tag of PREFLIGHT_AFFECTED_TAGS) {
const regex = new RegExp(`<${tag}.*>[^<]*</${tag}>`, "g");
const matches = [...currCode.matchAll(regex)].map((m) => m[0]);

for (const match of matches) {
const output = appendClass(id)(match);

if (output.code === match) {
// That means that className is not present
// We need to add it
currCode = currCode.replace(
match,
match.replace(`<${tag}`, `<${tag} class="${id}"`),
);
} else {
currCode = currCode.replace(match, output.code);
}
}
}

return {
code: currCode,
map: null,
};
};
17 changes: 16 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,24 @@ import uniqid from "uniqid";
import { getPostCssConfig, postCssPluginsToArray } from "./get-postcss-config";
import { prefixPlugin } from "./postcss/prefix-tailwind";
import { appendClass, appendClassForReact } from "./append-classes";
import { appendTags, appendTagsForReact } from "./append-tags";

const id = uniqid("d");

const appendForReact = (id: string) => (code: string) => {
return {
code: appendTagsForReact(id)(appendClassForReact(id)(code).code).code,
map: null,
};
};

const append = (id: string) => (code: string) => {
return {
code: appendTags(id)(appendClass(id)(code).code).code,
map: null,
};
};

const plugin = ({
react = false,
ignore = [],
Expand All @@ -33,7 +48,7 @@ const plugin = ({
},
};
},
transform: react ? appendClassForReact(id) : appendClass(id),
transform: react ? appendForReact(id) : append(id),
});

export default plugin;
8 changes: 7 additions & 1 deletion src/postcss/prefix-tailwind.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AcceptedPlugin } from "postcss";
import { splitClassNames } from "./tailwind-edgecases";
import { PREFLIGHT_AFFECTED_TAGS } from "./preflight";
/**
* Determine if class passes test
*
Expand Down Expand Up @@ -56,9 +57,14 @@ export const prefixPlugin = ({
rule.selectors = rule.selectors.map((selector) => {
// Is class selector
if (selector.indexOf(".") !== 0) {
// Fix for preflight reset
if (PREFLIGHT_AFFECTED_TAGS.has(selector)) {
return selector + "." + prefix;
}
return selector;
}
var classes = splitClassNames(selector)

var classes = splitClassNames(selector);

return classes
.map((cssClass) => {
Expand Down
25 changes: 25 additions & 0 deletions src/postcss/preflight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const PREFLIGHT_AFFECTED_TAGS = new Set([
"blockquote",
"dl",
"dd",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"hr",
"figure",
"p",
"pr",
"ol",
"ul",
"img",
"svg",
"video",
"canvas",
"audio",
"iframe",
"embed",
"object",
]);

0 comments on commit 86389ab

Please sign in to comment.