cal/packages/lib/cva/cva.ts
Jeroen Reumkens d64400d66b
Added proper dark mode support for buttons (#5603)
* Added proper dark mode support for buttons, and converted buttons to use CVA for better maintainable variant styling.

* Added animations to buttons.

* Added cva types to buttonbase type since thats imported in different places

* Fixed issue with styled buttons when false was pas for disabled instead of undefined. Added a small util function that now accepts arrays of variants, and creates all the possible combinations. This way we have less duplicate compoundvariants defined. This fixes the styles in the eventsinglelayout component.

* Undo disabling of api jest tests.

* Fixed remaining buttons using combined prop, which is replace by button group.

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2022-11-22 17:07:55 +00:00

62 lines
2.5 KiB
TypeScript

type ValidVariantTypes = string | number | null | boolean | undefined;
type Variants = Record<string, ValidVariantTypes | ValidVariantTypes[]> & { className: string };
/**
* Lets you use arrays for variants as well. This util combines all possible
* variants and returns an array with all possible options. Simply
* spread this in the compoundVariants.
*/
export const applyStyleToMultipleVariants = (variants: Variants) => {
const allKeysThatAreArrays = Object.keys(variants).filter((key) => Array.isArray(variants[key]));
const allKeysThatAreNotArrays = Object.keys(variants).filter((key) => !Array.isArray(variants[key]));
// Creates an object of all static options, ready to be merged in later with the array values.
const nonArrayOptions = allKeysThatAreNotArrays.reduce((acc, key) => {
return { ...acc, [key]: variants[key] };
}, {});
// Creates an array of all possible combinations of the array values.
// Eg if the variants object is { color: ["blue", "red"], size: ["small", "medium"] }
// then the result will be:
// [
// { color: "blue", size: "small" },
// { color: "blue", size: "medium" },
// { color: "red", size: "small" },
// { color: "red", size: "medium" },
// ]
const cartesianProductOfAllArrays = cartesianProduct(
allKeysThatAreArrays.map((key) => variants[key]) as ValidVariantTypes[][]
);
return cartesianProductOfAllArrays.map((variant) => {
const variantObject = variant.reduce((acc, value, index) => {
return { ...acc, [allKeysThatAreArrays[index]]: value };
}, {});
return {
...nonArrayOptions,
...variantObject,
};
});
};
/**
* A cartesian product is a final array that combines multiple arrays in ALL
* variations possible. For example:
*
* You have 3 arrays: [a, b], [1, 2], [y, z]
* The final result will be an array with all the different combinations:
* ["a", 1, "y"], ["a", 1, "z"], ["a", 2, "y"], ["a", 2, "z"], ["b", 1, "y"], etc
*
* We use this to create a params object for the static pages that combine multiple
* dynamic properties like 'stage' and 'meansOfTransport'. Resulting in an array
* with all different path combinations possible.
*
* @source: https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript
* TS Inspiration: https://gist.github.com/ssippe/1f92625532eef28be6974f898efb23ef
*/
export const cartesianProduct = <T extends ValidVariantTypes>(sets: T[][]) =>
sets.reduce<T[][]>(
(accSets, set) => accSets.flatMap((accSet) => set.map((value) => [...accSet, value])),
[[]]
);