Skip to content

Commit

Permalink
chore: update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
flozero committed Aug 30, 2024
2 parents 810536a + 936486f commit afd2714
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 116 deletions.
16 changes: 7 additions & 9 deletions packages/benchmark/benchmark.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const suite = new Benchmark.Suite();

import * as CVA from "./configs/cva.mjs";
import * as TAILWINDBUDDY from "./configs/tailwindbuddy.mjs";
import * as TAILWINDBUDDYPERFORMANCEMODEOFF from "./configs/tailwindbuddy-performance-mode-off.mjs";
import * as TAILWINDBUDDYPERFOFF from "./configs/tailwindbuddy-performance-off.mjs";
import * as TV from "./configs/tv.mjs";
import { twMerge } from "./configs/twMerge.config.mjs";

Expand All @@ -23,13 +23,11 @@ suite
});
})
.add(
"TAILWINDBUDDYPERFORMANCEMODEOFF - slots false - twMerge no - compound yes",
"TAILWINDBUDDYPERFOFF - slots false - twMerge no - compound yes",
function () {
TAILWINDBUDDYPERFORMANCEMODEOFF.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root(
{
size: "md",
}
);
TAILWINDBUDDYPERFOFF.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root({
size: "md",
});
}
)

Expand All @@ -48,10 +46,10 @@ suite
);
})
.add(
"TAILWINDBUDDYPERFORMANCEMODEOFF - slots false - twMerge yes - compound yes",
"TAILWINDBUDDYPERFOFF - slots false - twMerge yes - compound yes",
function () {
twMerge(
TAILWINDBUDDYPERFORMANCEMODEOFF.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root(
TAILWINDBUDDYPERFOFF.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root(
{
size: "md",
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { setupCompose } from "@busbud/tailwind-buddy";

const compose = setupCompose(["md", "lg", "xl", "2xl"], {
extraPerformanceDisabled: true,
disablePerformance: true,
});

const options = {
Expand Down
66 changes: 35 additions & 31 deletions packages/core/src/tailwind-buddy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import {
Variants,
} from "./types/variants";
import { buildArrayWithResponsivesFromDefault } from "./utils/arrays";
import { processStrings } from "./utils/strings";
import { extractValueFromVariantSlot } from "./utils/variants";

export const setupCompose = <Sc extends string>(
screens: Sc[],
options = { extraPerformanceDisabled: false }
options?: {
disablePerformance: boolean;
}
) => {
return <
V extends Variants<S>,
Expand All @@ -26,8 +29,14 @@ export const setupCompose = <Sc extends string>(
responsiveVariants?: R;
defaultVariants: DV;
}) => {
const transformedVariantDefinition = options?.disablePerformance
? processStrings(variantDefinition)
: variantDefinition;

return <Props>() => {
const slots = Object.keys(variantDefinition.slots) as Array<keyof S>;
const slots = Object.keys(transformedVariantDefinition.slots) as Array<
keyof S
>;

// Create an empty object and assert its type to avoid the TS error
const slotMethods = {} as {
Expand All @@ -43,19 +52,14 @@ export const setupCompose = <Sc extends string>(
// final list of classes to return we are going to populate as we go
const classesToReturn: string[] = [];

const slotDefaultClass = variantDefinition.slots[slot] || "";
const slotDefaultClass =
transformedVariantDefinition.slots[slot] || "";
if (slotDefaultClass) {
if (options.extraPerformanceDisabled) {
classesToReturn.push(
slotDefaultClass.replace(/\s+/g, " ").trim()
);
} else {
classesToReturn.push(slotDefaultClass);
}
classesToReturn.push(slotDefaultClass);
}

const mergedPropsWithDefaultsProperties = {
...variantDefinition.defaultVariants,
...transformedVariantDefinition.defaultVariants,
...props,
};

Expand All @@ -69,14 +73,14 @@ export const setupCompose = <Sc extends string>(
mergedPropsWithDefaultsProperties
);
// final trasnformed responsive object
const transformed_breakpoints: {
const transformedBreakpoints: {
[key: string]: { [key: string]: unknown };
} = { initial: {} };

//
for (const [variantKey, value] of responsiveArrayFromDefaults) {
// retrieve variant from definition. Continue when the key is not a variant but a props
const variant = variantDefinition.variants![variantKey];
const variant = transformedVariantDefinition.variants![variantKey];
if (!variant) continue;

const variantsDecomposedFromDefault: [
Expand All @@ -99,14 +103,14 @@ export const setupCompose = <Sc extends string>(
classesToReturn.push(classStr);
} else {
classStr.split(" ").forEach((v: string) => {
transformed_breakpoints[responsiveKey] =
transformed_breakpoints[responsiveKey] || {};
transformedBreakpoints[responsiveKey] =
transformedBreakpoints[responsiveKey] || {};
classesToReturn.push(`${responsiveKey}:${v}`);
});
}
} else {
transformed_breakpoints[responsiveKey] =
transformed_breakpoints[responsiveKey] || {};
transformedBreakpoints[responsiveKey] =
transformedBreakpoints[responsiveKey] || {};
}
}
}
Expand All @@ -115,32 +119,32 @@ export const setupCompose = <Sc extends string>(
const isOnlyInitial =
Object.keys(value).length === 1 && value["initial"];
if (isOnlyInitial) {
for (const responsiveKey in transformed_breakpoints) {
transformed_breakpoints[responsiveKey][key] =
for (const responsiveKey in transformedBreakpoints) {
transformedBreakpoints[responsiveKey][key] =
value[responsiveKey] || value["initial"];
}
} else {
for (const [responsiveKey, val] of Object.entries(value)) {
transformed_breakpoints[responsiveKey][key] = val;
transformedBreakpoints[responsiveKey][key] = val;
}
}
}

const transformed_breakpoints_entries = Object.entries(
transformed_breakpoints
const transformedBreakpoints_entries = Object.entries(
transformedBreakpoints
) as [string, any][];

if (
variantDefinition.compoundVariants &&
variantDefinition.compoundVariants!.length > 0
transformedVariantDefinition.compoundVariants &&
transformedVariantDefinition.compoundVariants!.length > 0
) {
for (const compound of variantDefinition.compoundVariants) {
for (const compound of transformedVariantDefinition.compoundVariants) {
const classes = extractValueFromVariantSlot(compound.class, slot);

for (const [
breakpoint,
value,
] of transformed_breakpoints_entries) {
] of transformedBreakpoints_entries) {
let validated = true;
const conditions = Object.entries(
compound.conditions as { [key: string]: any }
Expand Down Expand Up @@ -181,11 +185,11 @@ export const setupCompose = <Sc extends string>(

// Add the definition method
definition: () => ({
slots: variantDefinition.slots,
variants: variantDefinition.variants,
compoundVariants: variantDefinition.compoundVariants,
responsiveVariants: variantDefinition.responsiveVariants,
defaultVariants: variantDefinition.defaultVariants,
slots: transformedVariantDefinition.slots,
variants: transformedVariantDefinition.variants,
compoundVariants: transformedVariantDefinition.compoundVariants,
responsiveVariants: transformedVariantDefinition.responsiveVariants,
defaultVariants: transformedVariantDefinition.defaultVariants,
screens,
}),
};
Expand Down
126 changes: 126 additions & 0 deletions packages/core/src/utils/strings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { describe, expect, test } from "vitest";
import { processStrings } from "./strings";

const variant_complex = {
slots: {
root: `
1
${/* Some comment here */ ""}
2 ${/* And some comment here */ ""}
3
`,
},
variants: {
size: {
xs: {
root: `
4
${/* Some comment here */ ""}
5
6 ${/* And some comment here */ ""}
8
`,
},
md: `
9
${/* Some comment here */ ""}
10
11 ${/* And some comment here */ ""}
12
`,
},
test: {
awesome: `
13
${/* Some comment here */ ""}
14
15 ${/* And some comment here */ ""}
16
`,
},
},
defaultVariants: {
size: "md",
test: "awesome",
},
compoundVariants: [
{
conditions: {
size: "xs",
},
class: `
17
${/* Some comment here */ ""}
18
19 ${/* And some comment here */ ""}
20
`,
},
{
conditions: {
size: "md",
},
class: {
root: `
21
${/* Some comment here */ ""}
22
23 ${/* And some comment here */ ""}
24
`,
},
},
],
};

const expected_complex = {
slots: {
root: "1 2 3",
},
variants: {
size: {
xs: {
root: "4 5 6 8",
},
md: "9 10 11 12",
},
test: {
awesome: "13 14 15 16",
},
},
defaultVariants: {
size: "md",
test: "awesome",
},
compoundVariants: [
{
conditions: {
size: "xs",
},
class: "17 18 19 20",
},
{
conditions: {
size: "md",
},
class: {
root: "21 22 23 24",
},
},
],
};

describe("strings", () => {
test("should clean a string", () => {
// @ts-expect-error
const finalObg = processStrings(variant_complex);
expect(finalObg).toStrictEqual(expected_complex);
});
});
58 changes: 58 additions & 0 deletions packages/core/src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Slots } from "@/types/slots";
import {
Variants,
CompoundVariant,
DefaultVariants,
ResponsiveVariants,
} from "@/types/variants";

function cleanString(str: string): string {
// Remove comments
const noComments = str.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, "");

// Replace multiple whitespace characters (including newlines) with a single space
const noExtraSpaces = noComments.replace(/\s+/g, " ");

// Trim the string to remove leading and trailing spaces
return noExtraSpaces.trim();
}

export function processStrings<
V extends Variants<S>,
CV extends CompoundVariant<V, S>,
DV extends DefaultVariants<V, S>,
R extends ResponsiveVariants<V>,
S extends Slots
>(obj: {
slots: S;
variants?: V;
compoundVariants?: CV[];
responsiveVariants?: R;
defaultVariants: DV;
}): {
slots: S;
variants?: V;
compoundVariants?: CV[];
responsiveVariants?: R;
defaultVariants: DV;
} {
if (typeof obj === "string") {
// @ts-expect-error
return cleanString(obj);
} else if (Array.isArray(obj)) {
// @ts-expect-error
return obj.map(processStrings);
} else if (typeof obj === "object" && obj !== null) {
const processedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// @ts-expect-error
processedObj[key] = processStrings(obj[key]);
}
}
// @ts-expect-error
return processedObj;
} else {
return obj;
}
}
Loading

0 comments on commit afd2714

Please sign in to comment.