Skip to content

Commit

Permalink
Feat: Transform object - Merge values
Browse files Browse the repository at this point in the history
  • Loading branch information
black7375 committed Jan 14, 2024
1 parent 90de3b0 commit 6e7ec10
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 28 deletions.
73 changes: 53 additions & 20 deletions packages/transform-to-vanilla/src/transform-keys/merge-key.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,71 @@
import { NonNullableString } from "../types/string";

// == Type ================================================================
type HasSignInString = `${NonNullableString}$` | `${NonNullableString}_`;
type InputKeyValue = NonNullableString | HasSignInString;

// == Interface ================================================================
export function removeSignSimbol(keyStr: InputKeyValue) {
return hasSignSimbol(keyStr)
? keyStr.substring(0, keyStr.length - 1)
: keyStr;
export function removeMergeSymbol(keyStr: string) {
return keyStr.substring(0, keyStr.length - 1);
}

// == Utils ====================================================================
function hasSignSimbol(value: InputKeyValue): value is HasSignInString {
return value.endsWith("$") || value.endsWith("_");
export function mergeKeyInfo(keyStr: string) {
const isMergeToComma = keyStr.endsWith("$");
const isMergeToSpace = keyStr.endsWith("_");

return {
isMergeToComma,
isMergeToSpace,
isMergeSymbol: isMergeToComma || isMergeToSpace
};
}

// == Tests ====================================================================
if (import.meta.vitest) {
const { describe, it, expect } = import.meta.vitest;

describe.concurrent("Remove Key Sign Symbol", () => {
it("Has Sign Symbol to the end", () => {
expect(removeMergeSymbol("boxShadow$")).toBe("boxShadow");
expect(removeMergeSymbol("transform_")).toBe("transform");
});
});

describe.concurrent("Get key info has merge symbol", () => {
it("No Sign Symbol", () => {
expect(removeSignSimbol("boxShadow")).toBe("boxShadow");
expect(mergeKeyInfo("boxShadow")).toStrictEqual({
isMergeToComma: false,
isMergeToSpace: false,
isMergeSymbol: false
});
});
it("Has Sign Symbol to the end", () => {
expect(removeSignSimbol("boxShadow$")).toBe("boxShadow");
expect(removeSignSimbol("transform_")).toBe("transform");
expect(mergeKeyInfo("boxShadow$")).toStrictEqual({
isMergeToComma: true,
isMergeToSpace: false,
isMergeSymbol: true
});
expect(mergeKeyInfo("transform_")).toStrictEqual({
isMergeToComma: false,
isMergeToSpace: true,
isMergeSymbol: true
});
});
it("Has Sign Symbol in the middle or at the first", () => {
expect(removeSignSimbol("box$Shadow")).toBe("box$Shadow");
expect(removeSignSimbol("trans_form")).toBe("trans_form");
expect(removeSignSimbol("$boxShadow")).toBe("$boxShadow");
expect(removeSignSimbol("_transform")).toBe("_transform");
expect(mergeKeyInfo("box$Shadow")).toStrictEqual({
isMergeToComma: false,
isMergeToSpace: false,
isMergeSymbol: false
});
expect(mergeKeyInfo("trans_form")).toStrictEqual({
isMergeToComma: false,
isMergeToSpace: false,
isMergeSymbol: false
});
expect(mergeKeyInfo("$boxShadow")).toStrictEqual({
isMergeToComma: false,
isMergeToSpace: false,
isMergeSymbol: false
});
expect(mergeKeyInfo("_transform")).toStrictEqual({
isMergeToComma: false,
isMergeToSpace: false,
isMergeSymbol: false
});
});
});
}
77 changes: 69 additions & 8 deletions packages/transform-to-vanilla/src/transform-object/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { replacePseudoSelectors } from "@/transform-keys/simple-pseudo-selectors";
import { removeMergeSymbol, mergeKeyInfo } from "@/transform-keys/merge-key";
import { mergeToComma, mergeToSpace } from "@/transform-values/merge-values";
import { simplyImportant } from "@/transform-values/simply-important";
import type { StyleRule } from "@vanilla-extract/css";
import type {
Expand All @@ -6,7 +9,6 @@ import type {
CSSRuleValue,
VanillaStyleRuleValue
} from "@/types/style-rule";
import { replacePseudoSelectors } from "@/transform-keys/simple-pseudo-selectors";

// == Interface ================================================================
export function transformStyle(style: CSSRule) {
Expand All @@ -22,20 +24,45 @@ export function transformStyle(style: CSSRule) {
CSSRuleKey,
CSSRuleValue
][]) {
const { isMergeToComma, isMergeToSpace, isMergeSymbol } = mergeKeyInfo(key);

const transformedValue =
typeof value === "object"
? Array.isArray(value)
? value
: transformStyle(value as CSSRule) // TODO: Array
: typeof value === "string"
? simplyImportant(value)
: value;
const transformedKey = replacePseudoSelectors(key);
? transformArrayValue(value, isMergeToComma, isMergeToSpace)
: transformStyle(value as CSSRule)
: transformCommonValue(value);
const transformedKey = replacePseudoSelectors(
isMergeSymbol ? removeMergeSymbol(key) : key
);
result[transformedKey] = transformedValue as VanillaStyleRuleValue;
}
return result as StyleRule;
}

// == Utils ====================================================================
function transformArrayValue(
value: CSSRuleValue,
isMergeToComma: boolean,
isMergeToSpace: boolean
): CSSRuleValue {
const transformed = isMergeToComma
? mergeToComma(value as string[])
: isMergeToSpace
? mergeToSpace(value as string[])
: value;

return Array.isArray(transformed)
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: error TS2590: Expression produces a union type that is too complex to represent
(transformed.map(transformCommonValue) as CSSRuleValue)
: transformed;
}

function transformCommonValue(value: CSSRuleValue) {
return typeof value === "string" ? simplyImportant(value) : value;
}

// == Tests ====================================================================
if (import.meta.vitest) {
const { describe, it, expect } = import.meta.vitest;
Expand All @@ -48,7 +75,33 @@ if (import.meta.vitest) {
})
).toStrictEqual({
overflow: ["auto", "overlay"]
});
} satisfies StyleRule);
});

it("Merge Values", () => {
expect(
transformStyle({
boxShadow$: ["inset 0 0 10px #555", "0 0 20px black"],
transform_: ["scale(2)", "rotate(15deg)"]
})
).toStrictEqual({
boxShadow: "inset 0 0 10px #555, 0 0 20px black",
transform: "scale(2) rotate(15deg)"
} satisfies StyleRule);

expect(
transformStyle({
transform_: [
// Apply to all
"scale(2)",

// Fallback style
["rotate(28.64deg)", "rotate(0.5rad)"]
]
})
).toStrictEqual({
transform: ["scale(2) rotate(28.64deg)", "scale(2) rotate(0.5rad)"]
} satisfies StyleRule);
});

it("Simply Important", () => {
Expand All @@ -59,6 +112,14 @@ if (import.meta.vitest) {
).toStrictEqual({
color: "red !important"
} satisfies StyleRule);

expect(
transformStyle({
overflow: ["auto !", "overlay"]
})
).toStrictEqual({
overflow: ["auto !important", "overlay"]
} satisfies StyleRule);
});

it("Simple Psudo", () => {
Expand Down

0 comments on commit 6e7ec10

Please sign in to comment.