Skip to content

Commit

Permalink
chore: split into separate files
Browse files Browse the repository at this point in the history
  • Loading branch information
flozero committed Aug 28, 2024
1 parent 5d1d956 commit fed5289
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 115 deletions.
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 "./tailwind-buddy"
export { compose } from "./tailwind-buddy";
export type { VariantsProps } from "./types/definition";
119 changes: 6 additions & 113 deletions packages/core/src/tailwind-buddy.ts
Original file line number Diff line number Diff line change
@@ -1,113 +1,6 @@
type Slots = {
[slot: string]: string;
root: string;
};

type ResponsiveVariants<V> = (keyof V)[];

export type Variants<S extends Slots> = {
[variant: string]: {
[kind: string]:
| string
| {
[key in keyof S]?: string;
};
};
};

export type DefaultVariants<V extends Variants<S>, S extends Slots> = {
[K in keyof V]: K extends keyof V ? keyof V[K] : never;
};

export type CompoundVariant<V extends Variants<S>, S extends Slots> = {
conditions: {
[K in keyof V]?:
| (K extends keyof V ? keyof V[K] : never)
| (K extends keyof V ? keyof V[K] : never)[]
| boolean;
} & {
[K in string]?: string | string[] | boolean;
};
class: string | Record<string, string>;
};

// interface GlobalScreens {
// screens: string[];
// }

export type Screens = ["sm", "md", "lg", "xl"];

export type ResponsiveVariant<V, K extends keyof V> = {
["initial"]: keyof V[K];
} & {
[screen in Screens[number]]?: keyof V[K];
};

export type MergedProps<Props, V, R extends ResponsiveVariants<V>> = {
className?: string;
} & {
[K in keyof V]?: R extends undefined
? keyof V[K]
: K extends R[number]
? ResponsiveVariant<V, K> | keyof V[K]
: keyof V[K];
} & {
[K in keyof Props]?: Props[K];
};

export type TB = <
V extends Variants<S>,
CV extends CompoundVariant<V, S>,
DV extends DefaultVariants<V, S>,
R extends ResponsiveVariants<V>,
S extends Slots
>(options: {
slots: S;
variants?: V;
compoundVariants?: CV[];
responsiveVariants?: R;
defaultVariants: DV;
}) => <Props>() => {
[Slot in keyof S]: (props?: MergedProps<Props, V, R>) => string;
} & {
definition: () => {
slots: S;
variants?: V;
compoundVariants?: CV[];
responsiveVariants?: R;
defaultVariants: DV;
};
};

export type VariantsProps<
V extends Record<string, (...args: any[]) => unknown>
> = Parameters<V[keyof V]>[0];

export function extractValue(value: any, slot: string) {
if (typeof value === "string") return value.replace(/\s+/g, " ").trim();
else if (value?.[slot] && typeof value[slot] === "string")
return value[slot].replace(/\s+/g, " ").trim();
return undefined;
}

function buildArrayWithResponsivesFromDefault(obj: Record<string, any>): any[] {
const acc: any[] = [];
for (const [key, value] of Object.entries(obj)) {
if (value === undefined || value === null) continue;
else if (typeof value === "object") {
if (typeof value["initial"] === "undefined") {
throw new Error(
`initial value is missing for the variant ${key} ${value}`
);
} else {
acc.push([key, value]);
}
} else {
acc.push([key, { initial: value }]);
}
}
return acc;
}
import { TB } from "./types/definition";
import { buildArrayWithResponsivesFromDefault } from "./utils/arrays";
import { extractValueFromVariantSlot } from "./utils/variants";

export const compose: TB = (variantDefinition) => (): any => {
const slots = Object.keys(variantDefinition.slots);
Expand Down Expand Up @@ -156,7 +49,7 @@ export const compose: TB = (variantDefinition) => (): any => {
variantSubKey,
] of variantsDecomposedFromDefault) {
const variantValue = variant[variantSubKey];
const classStr = extractValue(variantValue, slot);
const classStr = extractValueFromVariantSlot(variantValue, slot);

if (classStr && classStr.length > 0) {
if (responsiveKey === "initial") {
Expand Down Expand Up @@ -199,7 +92,7 @@ export const compose: TB = (variantDefinition) => (): any => {
variantDefinition.compoundVariants!.length > 0
) {
for (const compound of variantDefinition.compoundVariants) {
const classes = extractValue(compound.class, slot);
const classes = extractValueFromVariantSlot(compound.class, slot);

for (const [breakpoint, value] of transformed_breakpoints_entries) {
let validated = true;
Expand All @@ -216,7 +109,7 @@ export const compose: TB = (variantDefinition) => (): any => {
}
}
if (validated && classes) {
const classStr = extractValue(classes, slot);
const classStr = extractValueFromVariantSlot(classes, slot);
if (classStr) {
if (breakpoint === "initial") {
classesToReturn.push(classStr);
Expand Down
36 changes: 36 additions & 0 deletions packages/core/src/types/definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { MergedProps } from "./props";
import type { Slots } from "./slots";
import type {
Variants,
CompoundVariant,
DefaultVariants,
ResponsiveVariants,
} from "./variants";

export type TB = <
V extends Variants<S>,
CV extends CompoundVariant<V, S>,
DV extends DefaultVariants<V, S>,
R extends ResponsiveVariants<V>,
S extends Slots
>(options: {
slots: S;
variants?: V;
compoundVariants?: CV[];
responsiveVariants?: R;
defaultVariants: DV;
}) => <Props>() => {
[Slot in keyof S]: (props?: MergedProps<Props, V, R>) => string;
} & {
definition: () => {
slots: S;
variants?: V;
compoundVariants?: CV[];
responsiveVariants?: R;
defaultVariants: DV;
};
};

export type VariantsProps<
V extends Record<string, (...args: any[]) => unknown>
> = Parameters<V[keyof V]>[0];
13 changes: 13 additions & 0 deletions packages/core/src/types/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ResponsiveVariant, ResponsiveVariants } from "./variants";

export type MergedProps<Props, V, R extends ResponsiveVariants<V>> = {
className?: string;
} & {
[K in keyof V]?: R extends undefined
? keyof V[K]
: K extends R[number]
? ResponsiveVariant<V, K> | keyof V[K]
: keyof V[K];
} & {
[K in keyof Props]?: Props[K];
};
5 changes: 5 additions & 0 deletions packages/core/src/types/screens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// interface GlobalScreens {
// screens: string[];
// }

export type Screens = ["sm", "md", "lg", "xl"];
4 changes: 4 additions & 0 deletions packages/core/src/types/slots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type Slots = {
[slot: string]: string;
root: string;
};
36 changes: 36 additions & 0 deletions packages/core/src/types/variants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Screens } from "./screens";
import { Slots } from "./slots";

export type ResponsiveVariants<V> = (keyof V)[];

export type Variants<S extends Slots> = {
[variant: string]: {
[kind: string]:
| string
| {
[key in keyof S]?: string;
};
};
};

export type DefaultVariants<V extends Variants<S>, S extends Slots> = {
[K in keyof V]: K extends keyof V ? keyof V[K] : never;
};

export type CompoundVariant<V extends Variants<S>, S extends Slots> = {
conditions: {
[K in keyof V]?:
| (K extends keyof V ? keyof V[K] : never)
| (K extends keyof V ? keyof V[K] : never)[]
| boolean;
} & {
[K in string]?: string | string[] | boolean;
};
class: string | Record<string, string>;
};

export type ResponsiveVariant<V, K extends keyof V> = {
["initial"]: keyof V[K];
} & {
[screen in Screens[number]]?: keyof V[K];
};
20 changes: 20 additions & 0 deletions packages/core/src/utils/arrays.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const buildArrayWithResponsivesFromDefault = (
obj: Record<string, any>
): any[] => {
const acc: any[] = [];
for (const [key, value] of Object.entries(obj)) {
if (value === undefined || value === null) continue;
else if (typeof value === "object") {
if (typeof value["initial"] === "undefined") {
throw new Error(
`initial value is missing for the variant ${key} ${value}`
);
} else {
acc.push([key, value]);
}
} else {
acc.push([key, { initial: value }]);
}
}
return acc;
};
6 changes: 6 additions & 0 deletions packages/core/src/utils/variants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function extractValueFromVariantSlot(value: any, slot: string) {
if (typeof value === "string") return value.replace(/\s+/g, " ").trim();
else if (value?.[slot] && typeof value[slot] === "string")
return value[slot].replace(/\s+/g, " ").trim();
return undefined;
}

0 comments on commit fed5289

Please sign in to comment.