Skip to content

Commit

Permalink
feat!: screens overrides, new setupCompose, performance mode, simplif…
Browse files Browse the repository at this point in the history
…y tailwind config
  • Loading branch information
flozero committed Aug 30, 2024
1 parent 2dab469 commit bc0d623
Show file tree
Hide file tree
Showing 34 changed files with 704 additions and 561 deletions.
34 changes: 29 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Tailwind Buddy addresses common challenges in managing Tailwind classes for comp
- SSR-friendly class generation, both responsive and non-responsive
- Ability to use slots for component composition
- Compound variants that work responsively, overriding classes based on variant values and other props
- High-performance variant utility, as demonstrated in [our benchmarks](./packages/benchmark/README.md)
- High-performance variant utility, as demonstrated in [our benchmarks](./packages/benchmark/README.md) when enabling performance mode.

This library is inspired by [CVA](https://cva.style/docs) and [tailwind-variants](https://github.com/nextui-org/tailwind-variants), offering our unique approach to solving common Tailwind challenges.

Expand All @@ -27,12 +27,24 @@ This library is inspired by [CVA](https://cva.style/docs) and [tailwind-variants
pnpm add @busbud/tailwind-buddy
```

## Setup compose function

Tailwind buddy expose a `setupCompose` function. Create a `tailwind-buddy-interface.ts`

```ts
import { setupCompose } from "@busbud/tailwind-buddy";

export type Screens = "sm" | "md";
export const screens: Screens[] = ["sm", "md"];
export const compose = setupCompose<Screens>(screens);
```

## Usage

Let's create a button component with two variants, featuring different background colors on mobile and desktop.

```tsx
import { compose } from "@busbud/tailwind-buddy";
import { compose } from "../tailwind-buddy-interface.ts";
import type { VariantsProps } from "@busbud/tailwind-buddy";

interface ButtonBaseProps
Expand Down Expand Up @@ -157,7 +169,7 @@ export const buttonVariants = compose({
class: "font-bold",
},
],
});
})();
```

## Responsive Variants
Expand All @@ -172,7 +184,7 @@ To enable responsive variants:
export const buttonVariants = compose({
// ... other configurations ...
responsiveVariants: ["intent"],
});
})();

// Usage in a React component
import { twMerge } from "tailwind-merge";
Expand Down Expand Up @@ -202,11 +214,23 @@ import { buttonVariants } from "./path-to-your-variants";
// As you now Expect responsive for this component make sure to import the buttonVariants
export default {
// ... other Tailwind configurations ...
safelist: generateSafeList([buttonVariants], ["sm", "md", "lg", "xl"]), // those values are required to align with tailwind breakpoints and make them available as in the example above
safelist: generateSafeList([buttonVariants]), // those values are required to align with tailwind breakpoints and make them available as in the example above
//
};
```

## extraPerformanceDisabled

We do not support writing a variant definition using template string. You can enable it by updating your setupCompose:

```ts
export const compose = setupCompose<Screens>(screens, {
extraPerformanceDisabled: true,
});
```

Take in consideration that this is going to drop the performance hard check the performance for more information.

## Tailwind Autocomplete in VSCode (Optional)

For Tailwind class autocomplete in VSCode, add the following to your `.vscode/settings.json`:
Expand Down
4 changes: 2 additions & 2 deletions packages/benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ come back to benchmark folder and run
`pnpm test`
To make sure we do have the same outputs between library

## Our current benchmarks. TCA is our library At this time we had another name
## Our current benchmarks. TCA is our library At this time we had another name

![](./benchmarks.png)
![Screenshot 2024-08-30 at 1 51 17 AM](https://github.com/user-attachments/assets/e84a33f5-2dec-4e71-8213-61bc918c6fff)
91 changes: 60 additions & 31 deletions packages/benchmark/benchmark.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,68 @@ import Benchmark from "benchmark";

const suite = new Benchmark.Suite();

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

suite

// TV - slots false - twMerge no - compound yes
.add("TV - slots false - twMerge no - compound yes", function () {
TV.noSlotsAndCompoundNoTwMergeNoResponsive.avatar({ size: "md" });
})
.add("CVA - slots false - twMerge no - compound yes", function () {
CVA.noSlotsAndCompoundNoTwMergeNoResponsive.avatar({ size: "md" });
})
.add("TAILWINDBUDDY - slots false - twMerge no - compound yes", function () {
TAILWINDBUDDY.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root({ size: "md" });
})
// TV - slots false - twMerge no - compound yes
.add("TV - slots false - twMerge no - compound yes", function () {
TV.noSlotsAndCompoundNoTwMergeNoResponsive.avatar({ size: "md" });
})
.add("CVA - slots false - twMerge no - compound yes", function () {
CVA.noSlotsAndCompoundNoTwMergeNoResponsive.avatar({ size: "md" });
})
.add("TAILWINDBUDDY - slots false - twMerge no - compound yes", function () {
TAILWINDBUDDY.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root({
size: "md",
});
})
.add(
"TAILWINDBUDDYPERFORMANCEMODE - slots false - twMerge no - compound yes",
function () {
TAILWINDBUDDYPERFORMANCEMODE.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root(
{
size: "md",
}
);
}
)

// TV - slots false - twMerge yes - compound yes
.add("TV - slots false - twMerge yes - compound yes", function () {
TV.noSlotsCompound.avatar({ size: "md" });
})
.add("CVA - slots false - twMerge yes - compound yes", function () {
twMerge(CVA.noSlotsAndCompoundNoTwMergeNoResponsive.avatar({ size: "md" }));
})
.add("TAILWINDBUDDY - slots false - twMerge yes - compound yes", function () {
twMerge(TAILWINDBUDDY.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root({ size: "md" }));
})
// TV - slots false - twMerge yes - compound yes
.add("TV - slots false - twMerge yes - compound yes", function () {
TV.noSlotsCompound.avatar({ size: "md" });
})
.add("CVA - slots false - twMerge yes - compound yes", function () {
twMerge(CVA.noSlotsAndCompoundNoTwMergeNoResponsive.avatar({ size: "md" }));
})
.add("TAILWINDBUDDY - slots false - twMerge yes - compound yes", function () {
twMerge(
TAILWINDBUDDY.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root({
size: "md",
})
);
})
.add(
"TAILWINDBUDDYPERFORMANCEMODE - slots false - twMerge yes - compound yes",
function () {
twMerge(
TAILWINDBUDDYPERFORMANCEMODE.noSlotsAndCompoundNoTwMergeNoResponsive.avatar.root(
{
size: "md",
}
)
);
}
)

.on("cycle", function (event) {
console.log(String(event.target));
})
.on("complete", function () {
console.log("Fastest is " + this.filter("fastest").map("name"));
})
.run({async: true});
.on("cycle", function (event) {
console.log(String(event.target));
})
.on("complete", function () {
console.log("Fastest is " + this.filter("fastest").map("name"));
})
.run({ async: true });
Binary file removed packages/benchmark/benchmarks.png
Binary file not shown.
51 changes: 51 additions & 0 deletions packages/benchmark/configs/tailwindbuddy-performance-mode.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { setupCompose } from "@busbud/tailwind-buddy";

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

const options = {
slots: {
root: "relative flex shrink-0 overflow-hidden rounded-full",
},
variants: {
size: {
xs: "h-6 w-6",
sm: "h-8 w-8",
md: "h-10 w-10",
lg: "h-12 w-12",
xl: "h-14 w-14",
},
},
defaultVariants: {
size: "md",
},
compoundVariants: [
{
conditions: {
size: ["xs", "sm"],
},
class: "ring-1",
},
{
conditions: {
size: ["md", "lg", "xl", "2xl"],
},
class: "ring-2",
},
],
};

export const noSlotsAndCompoundNoTwMergeNoResponsive = {
avatar: compose(options)(),
};

export const slotsAndCompoundNoTwMergeNoResponsive = {
avatar: compose({
...options,
slots: {
...options.slots,
label: "sr-only",
},
})(),
};
78 changes: 40 additions & 38 deletions packages/benchmark/configs/tailwindbuddy.mjs
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
import { compose } from "@busbud/tailwind-buddy"
import { setupCompose } from "@busbud/tailwind-buddy";

const compose = setupCompose(["md", "lg", "xl", "2xl"]);

const options = {
slots: {
root: "relative flex shrink-0 overflow-hidden rounded-full"
slots: {
root: "relative flex shrink-0 overflow-hidden rounded-full",
},
variants: {
size: {
xs: "h-6 w-6",
sm: "h-8 w-8",
md: "h-10 w-10",
lg: "h-12 w-12",
xl: "h-14 w-14",
},
variants: {
size: {
xs: "h-6 w-6",
sm: "h-8 w-8",
md: "h-10 w-10",
lg: "h-12 w-12",
xl: "h-14 w-14",
},
},
defaultVariants: {
size: "md",
},
compoundVariants: [
{
conditions: {
size: ["xs", "sm"],
},
class: "ring-1",
},
defaultVariants: {
size: "md",
{
conditions: {
size: ["md", "lg", "xl", "2xl"],
},
class: "ring-2",
},
compoundVariants: [
{
conditions: {
size: ["xs", "sm"],
},
class: "ring-1",
},
{
conditions: {
size: ["md", "lg", "xl", "2xl"],
},
class: "ring-2",
},
],
}
],
};

export const noSlotsAndCompoundNoTwMergeNoResponsive = {
avatar: compose(options)(),
}
avatar: compose(options)(),
};

export const slotsAndCompoundNoTwMergeNoResponsive = {
avatar: compose({
...options,
slots: {
...options.slots,
label: "sr-only"
},
})(),
}
avatar: compose({
...options,
slots: {
...options.slots,
label: "sr-only",
},
})(),
};
4 changes: 2 additions & 2 deletions packages/core/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { generateSafeList } from "./utils/tailwind-utils";
export { compose } from "./tailwind-buddy";
export type { VariantsProps } from "./types/definition";
export { setupCompose } from "./tailwind-buddy";
export type { VariantsProps } from "./tailwind-buddy";
Loading

0 comments on commit bc0d623

Please sign in to comment.