@crossed/styled
Version:
A universal & performant styling library for React Native, Next.js & React
50 lines (44 loc) • 1.53 kB
text/typescript
/**
* Copyright (c) Paymium.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root of this projects source tree.
*/
import { createMethods } from './createMethods';
import { AllAvailableStyles, CrossedMethods } from './types';
import { merge } from 'ts-deepmerge';
type AllKeys<T> = T extends any ? keyof T : never;
// eslint-disable-next-line no-unused-vars
type PickType<T, K extends AllKeys<T>> = T extends { [k in K]?: any }
? T[K]
: undefined;
type Merge<T extends object> = {
[k in AllKeys<T>]: PickType<T, k>;
};
export type ExtractStyle<S extends CrossedMethods<any>> =
S extends CrossedMethods<infer D, any> ? D : never;
export const composeStyles = <
T extends (CrossedMethods<any> | AllAvailableStyles | false | void | null)[],
P extends Exclude<T[number], false | void | AllAvailableStyles>,
>(
...styles: T
) => {
// console.log(styles);
let stylesNative = {};
const stylesVerified = styles.flat(Infinity).reduce((acc, e: any) => {
if (!e) return acc;
if ('original' in e && e.original) {
acc.push(e.original);
}
if ('stylesParent' in e && e.stylesParent) {
stylesNative = { ...stylesNative, ...e.stylesParent };
return acc;
}
if (typeof e !== 'function' && typeof e === 'object' && !e.style) {
stylesNative = { ...stylesNative, ...e };
}
return acc;
}, []) as P[];
const styleMerged = merge(...stylesVerified) as Merge<P['original']>;
return createMethods(styleMerged, stylesNative);
};