Skip to content

Commit

Permalink
Merge pull request #24 from joe-bell/fix/false-boolean-variants
Browse files Browse the repository at this point in the history
Fix Behaviour of Falsey Boolean Variants
  • Loading branch information
joe-bell authored Apr 5, 2022
2 parents 95f26c4 + 13be394 commit ac03505
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ const component = cva("base", options);
1. `options` _(optional)_
- `variants`: your variants schema
- `compoundVariants`: variants based on a combination of previously defined variants
- `defaultVariants`: set default values for previously defined variants
- `defaultVariants`: set default values for previously defined variants.
_note: these default values can be removed completely by setting the variant as `null`_

#### Returns

Expand Down
32 changes: 30 additions & 2 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ describe("cva", () => {
],
[
{ intent: "secondary", size: null },
"button font-semibold border rounded button--secondary bg-white text-gray-800 border-gray-400 hover:bg-gray-100 button--enabled cursor-pointer button--medium text-base py-2 px-4",
"button font-semibold border rounded button--secondary bg-white text-gray-800 border-gray-400 hover:bg-gray-100 button--enabled cursor-pointer",
],
[
{ intent: "secondary", size: undefined },
Expand Down Expand Up @@ -545,6 +545,10 @@ describe("cva", () => {
{ size: "small" },
"button font-semibold border rounded button--small text-sm py-1 px-2",
],
[
{ disabled: false },
"button font-semibold border rounded button--enabled cursor-pointer",
],
[
{ disabled: true },
"button font-semibold border rounded button--disabled opacity-050 cursor-not-allowed",
Expand All @@ -565,10 +569,18 @@ describe("cva", () => {
{ intent: "warning", size: "large" },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--large text-lg py-2.5 px-4",
],
[
{ intent: "warning", size: "large", disabled: null },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--large text-lg py-2.5 px-4",
],
[
{ intent: "warning", size: "large", disabled: true },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--disabled opacity-050 cursor-not-allowed button--large text-lg py-2.5 px-4 button--warning-disabled text-black",
],
[
{ intent: "warning", size: "large", disabled: false },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--enabled cursor-pointer button--large text-lg py-2.5 px-4 button--warning-enabled text-gray-800",
],
])("button(%o)", (options, expected) => {
test(`returns ${expected}`, () => {
expect(buttonWithStringClasses(options)).toBe(expected);
Expand Down Expand Up @@ -728,13 +740,21 @@ describe("cva", () => {
{ size: "small" },
"button font-semibold border rounded button--primary bg-blue-500 text-white border-transparent hover:bg-blue-600 button--enabled cursor-pointer button--small text-sm py-1 px-2",
],
[
{ disabled: null },
"button font-semibold border rounded button--primary bg-blue-500 text-white border-transparent hover:bg-blue-600 button--medium text-base py-2 px-4 button--primary-medium uppercase",
],
[
{ disabled: false },
"button font-semibold border rounded button--primary bg-blue-500 text-white border-transparent hover:bg-blue-600 button--enabled cursor-pointer button--medium text-base py-2 px-4 button--primary-medium uppercase",
],
[
{ disabled: true },
"button font-semibold border rounded button--primary bg-blue-500 text-white border-transparent hover:bg-blue-600 button--disabled opacity-050 cursor-not-allowed button--medium text-base py-2 px-4 button--primary-medium uppercase",
],
[
{ intent: "secondary", size: null },
"button font-semibold border rounded button--secondary bg-white text-gray-800 border-gray-400 hover:bg-gray-100 button--enabled cursor-pointer button--medium text-base py-2 px-4",
"button font-semibold border rounded button--secondary bg-white text-gray-800 border-gray-400 hover:bg-gray-100 button--enabled cursor-pointer",
],
[
{ intent: "secondary", size: undefined },
Expand All @@ -748,10 +768,18 @@ describe("cva", () => {
{ intent: "warning", size: "large" },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--enabled cursor-pointer button--large text-lg py-2.5 px-4 button--warning-enabled text-gray-800",
],
[
{ intent: "warning", size: "large", disabled: null },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--large text-lg py-2.5 px-4",
],
[
{ intent: "warning", size: "large", disabled: true },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--disabled opacity-050 cursor-not-allowed button--large text-lg py-2.5 px-4 button--warning-disabled text-black",
],
[
{ intent: "warning", size: "large", disabled: false },
"button font-semibold border rounded button--warning bg-yellow-500 border-transparent hover:bg-yellow-600 button--enabled cursor-pointer button--large text-lg py-2.5 px-4 button--warning-enabled text-gray-800",
],
])("button(%o)", (options, expected) => {
test(`returns ${expected}`, () => {
expect(buttonWithStringClasses(options)).toBe(expected);
Expand Down
21 changes: 16 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
export type VariantProps<Component extends (...args: any) => any> =
OmitUndefined<Parameters<Component>[0]>;

const booleanToString = <T extends unknown>(value: T) =>
typeof value === "boolean" ? `${value}` : value;

/* cx
============================================ */

Expand Down Expand Up @@ -53,11 +56,19 @@ export const cva =
const { variants, defaultVariants } = config;

const getVariantClassNames = Object.keys(variants).map(
(variant: keyof typeof variants) =>
variants[variant][
(props?.[variant as keyof typeof props] ||
defaultVariants?.[variant]) as keyof typeof variants[typeof variant]
]
(variant: keyof typeof variants) => {
const variantProp = props?.[variant as keyof typeof props];
const defaultVariantProp = defaultVariants?.[variant];

if (variantProp === null) return null;

const variantKey = (booleanToString(variantProp) ||
booleanToString(
defaultVariantProp
)) as keyof typeof variants[typeof variant];

return variants[variant][variantKey];
}
);

const propsWithoutUndefined =
Expand Down

0 comments on commit ac03505

Please sign in to comment.