Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
cullophid committed Jul 4, 2024
1 parent ab40341 commit 00d1a13
Show file tree
Hide file tree
Showing 45 changed files with 3,170 additions and 1,607 deletions.
55 changes: 54 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1 +1,54 @@
{"version":"0.1.0","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","files":["dist","src"],"engines":{"node":">=10"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test","lint":"tsdx lint","prepare":"tsdx build","size":"size-limit","analyze":"size-limit --why"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":true,"singleQuote":true,"trailingComma":"es5"},"name":"tailwind-parser","author":"cullophid","module":"dist/tailwind-parser.esm.js","size-limit":[{"path":"dist/tailwind-parser.cjs.production.min.js","limit":"10 KB"},{"path":"dist/tailwind-parser.esm.js","limit":"10 KB"}],"devDependencies":{"@size-limit/preset-small-lib":"^11.1.4","husky":"^9.0.11","size-limit":"^11.1.4","tsdx":"^0.14.1","tslib":"^2.6.3","typescript":"^3.9.10"}}
{
"version": "0.1.0",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"engines": {
"node": ">=10"
},
"scripts": {
"start": "tsdx watch",
"build": "tsdx build",
"test": "tsdx test",
"lint": "tsdx lint",
"prepare": "tsdx build",
"size": "size-limit",
"analyze": "size-limit --why"
},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
},
"name": "@toddledev/tailwind-parser",
"author": "cullophid",
"module": "dist/tailwind-parser.esm.js",
"size-limit": [
{
"path": "dist/tailwind-parser.cjs.production.min.js",
"limit": "10 KB"
},
{
"path": "dist/tailwind-parser.esm.js",
"limit": "10 KB"
}
],
"devDependencies": {
"@size-limit/preset-small-lib": "^11.1.4",
"husky": "^9.0.11",
"size-limit": "^11.1.4",
"tsdx": "^0.14.1",
"tslib": "^2.6.3",
"typescript": "^3.9.10"
}
}
97 changes: 97 additions & 0 deletions src/parseBackgroundClasses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { CSSProperties, colorMap } from "./tailwind-parser";


export function parseBackgroundClasses(className: string): CSSProperties | null {
// Background size
if (/^bg-(auto|cover|contain)$/.test(className)) {
return { "background-size": className.split("-")[1] };
}

// Background position
const positionMap: Record<string, string> = {
"bg-bottom": "bottom",
"bg-top": "top",
"bg-center": "center",
"bg-left": "left",
"bg-left-bottom": "left bottom",
"bg-left-top": "left top",
"bg-right": "right",
"bg-right-bottom": "right bottom",
"bg-right-top": "right top",
};
if (positionMap[className]) {
return { "background-position": positionMap[className] };
}

// Background attachment
if (/^bg-(fixed|local|scroll)$/.test(className)) {
return { "background-attachment": className.split("-")[1] };
}

// Background repeat
if (/^bg-(no-repeat|repeat|repeat-x|repeat-y|repeat-round|repeat-space)$/.test(
className
)) {
return { "background-repeat": className.split("-").slice(1).join("-") };
}

// Background opacity
const opacityMatch = className.match(/^bg-opacity-(\d+)$/);
if (opacityMatch) {
return { "--tw-bg-opacity": (parseInt(opacityMatch[1]) / 100).toString() };
}

// Background clip
if (/^bg-clip-(border|content|padding|text)$/.test(className)) {
return { "background-clip": className.split("-")[2] };
}

const colorMatch = className.match(/^bg-(\w+)(?:-(\d+))?$/);
if (colorMatch) {
const color = colorMatch[1];
const shade = colorMatch[2] || (color === "black" || color === "white" ? null : "500");
if (colorMap[color]) {
return {
"background-color": shade
? (colorMap[color] as Record<string, string>)[shade]
: (colorMap[color] as string),
};
}
}

// Background gradients
if (/^bg-gradient-to-(t|tr|r|br|b|bl|l|tl)$/.test(className)) {
const direction = className.split("-").pop() as string;
const directionMap: Record<string, string> = {
t: "to top",
tr: "to top right",
r: "to right",
br: "to bottom right",
b: "to bottom",
bl: "to bottom left",
l: "to left",
tl: "to top left",
};
return {
"background-image": `linear-gradient(${directionMap[direction]}, var(--tw-gradient-stops))`,
};
}

// Gradient color stops
const gradientStopMatch = className.match(/^(from|via|to)-(\w+)(?:-(\d+))?$/);
if (gradientStopMatch) {
const [, position, color, shade] = gradientStopMatch;
if (colorMap[color]) {
const colorValue = shade
? (colorMap[color] as Record<string, string>)[shade]
: (colorMap[color] as Record<string, string>)["500"] || (colorMap[color] as string);
return {
[`--tw-gradient-${position}`]: colorValue,
"--tw-gradient-stops": "var(--tw-gradient-from), var(--tw-gradient-to)",
};
}
}

// If no match is found
return null;
}
159 changes: 159 additions & 0 deletions src/parseBorderClasses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { CSSProperties, colorMap } from "./tailwind-parser";

export function parseBorderClasses(className: string): CSSProperties | null {

// Border color
const borderColorMatch = className.match(
/^border-(transparent|current|black|white|(\w+)-(50|[1-9][0-9]{2}))$/
);
if (borderColorMatch) {
const [, colorName, colorFamily, colorShade] = borderColorMatch;
let color: string | undefined;
if (colorName in colorMap) {
color = colorMap[colorName] as string;
} else if (colorFamily && colorShade) {
color = (colorMap[colorFamily] as Record<string, string>)?.[colorShade];
}
if (color) {
return { "border-color": color };
}
}

// Border style
const borderStyleMatch = className.match(
/^border-(solid|dashed|dotted|double|none)$/
);
if (borderStyleMatch) {
return { "border-style": borderStyleMatch[1] };
}

// Border width
const borderWidthMatch = className.match(/^border(-([trbl]))?(-(\d+))?$/);
if (borderWidthMatch) {
const [, , side, , width] = borderWidthMatch;
const prop = side
? `border-${side === "r"
? "right"
: side === "l"
? "left"
: side === "t"
? "top"
: "bottom"}-width`
: "border-width";
const value = width ? `${parseInt(width) / 4}rem` : "1px";
return { [prop]: value };
}

// Border opacity
const borderOpacityMatch = className.match(/^border-opacity-(\d+)$/);
if (borderOpacityMatch) {
return { "--tw-border-opacity": borderOpacityMatch[1] + "%" };
}

// Divide
const divideMatch = className.match(/^divide-(x|y)(-reverse)?(-(\d+))?$/);
if (divideMatch) {
const [, direction, reverse, , size] = divideMatch;
const prop = `--tw-divide-${direction}-reverse`;
const value = reverse ? "1" : "0";
const widthProp = `border-${direction === "x" ? "left" : "top"}-width`;
const widthValue = size ? `${parseInt(size) / 4}rem` : "1px";
return {
[prop]: value,
[widthProp]: widthValue,
"& > :not([hidden]) ~ :not([hidden])": {
[prop]: value,
[widthProp]: widthValue,
},
};
}


// Border collapse
if (className === "border-collapse") {
return { "border-collapse": "collapse" };
}
if (className === "border-separate") {
return { "border-collapse": "separate" };
}

// Rounded corners
const roundedMatch = className.match(
/^rounded(-([trblse]|tl|tr|br|bl))?(-(\w+))?$/
);
if (roundedMatch) {
const [, , side, , size] = roundedMatch;
let props: string[];
if (side) {
switch (side) {
case "t":
props = ["border-top-left-radius", "border-top-right-radius"];
break;
case "r":
props = ["border-top-right-radius", "border-bottom-right-radius"];
break;
case "b":
props = ["border-bottom-left-radius", "border-bottom-right-radius"];
break;
case "l":
props = ["border-top-left-radius", "border-bottom-left-radius"];
break;
case "tl":
props = ["border-top-left-radius"];
break;
case "tr":
props = ["border-top-right-radius"];
break;
case "br":
props = ["border-bottom-right-radius"];
break;
case "bl":
props = ["border-bottom-left-radius"];
break;
default:
props = ["border-radius"];
}
} else {
props = ["border-radius"];
}

let value = "0.25rem";
if (size) {
switch (size) {
case "none":
value = "0";
break;
case "sm":
value = "0.125rem";
break;
case "md":
value = "0.375rem";
break;
case "lg":
value = "0.5rem";
break;
case "xl":
value = "0.75rem";
break;
case "2xl":
value = "1rem";
break;
case "3xl":
value = "1.5rem";
break;
case "full":
value = "9999px";
break;
}
}

const result: CSSProperties = {};
props.forEach(prop => {
result[prop] = value;
});
return result;
}

// If no match is found
return null;
}
32 changes: 32 additions & 0 deletions src/parseDisplayClasses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { CSSProperties } from "./tailwind-parser";

export function parseDisplayClasses(className: string): CSSProperties | null {
interface DisplayMap {
[key: string]: string;
}
// Box
if (/^box-(border|content)$/.test(className)) {
return { "box-sizing": className.split("-")[1] };
}

// Display
const displayMap: DisplayMap = {
block: "block",
hidden: "none",
inline: "inline",
"inline-block": "inline-block",
"inline-flex": "inline-flex",
"inline-grid": "inline-grid",
flex: "flex",
grid: "grid",
"flow-root": "flow-root",
};

if (className in displayMap) {
return { display: displayMap[className] };
}


// If no match is found
return null;
}
Loading

0 comments on commit 00d1a13

Please sign in to comment.