Skip to content

Commit

Permalink
feat: generate utility function for all category types ( #293)
Browse files Browse the repository at this point in the history
  • Loading branch information
muhammadsammy committed Oct 22, 2021
1 parent 233390b commit a8173c7
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 49 deletions.
9 changes: 3 additions & 6 deletions src/cli/core/ClassnamesGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {nonConfigurableClassNames} from '../lib/non-configurable';
import {
TAllClassnames, Backgrounds, Layout, Borders, Tables, Effects,
Interactivity, TransitionsAndAnimations, Transforms, Accessibility, SVG,
FlexBox, Grid, Spacing, Sizing, Typography, TGeneratedClassnames, Filters
FlexBox, Grid, Spacing, Sizing, Typography, Filters
} from '../types/classes';
import {TConfigTheme, TConfigDarkMode} from '../types/config';
import {tailwindLabsPlugins} from '../lib/tailwindlabs-plugins';
Expand Down Expand Up @@ -71,11 +71,8 @@ export class ClassnamesGenerator {
/**
* Get the generated classnames.
*/
public generate = (): TGeneratedClassnames => {
return {
regularClassnames: this._generatedRegularClassnames,
pseudoClassnames: this._generatedPseudoClassnames,
};
public generate = (): TAllClassnames => {
return this._generatedRegularClassnames;
};

private layout = (): Layout | Record<keyof Layout | 'content', string[]> => {
Expand Down
107 changes: 69 additions & 38 deletions src/cli/core/FileContentGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import _ from 'lodash';
import {TAllClassnames, TGeneratedClassnames} from '../types/classes';
import {TAllClassnames} from '../types/classes';
import {TailwindConfigParser} from './TailwindConfigParser';

export class FileContentGenerator {
private _configPrefix: string;
private _generatedClassNames: TGeneratedClassnames;
private _configParser: TailwindConfigParser;
private _generatedClassNames: TAllClassnames;

/**
* Initializes a new instance of the `FileContentGenerator` class.
* @param generatedClassnames The generated classnames to put in the template.
*/
constructor(generatedClassnames: TGeneratedClassnames, ConfigPrefix: string) {
this._configPrefix = ConfigPrefix;
constructor(generatedClassnames: TAllClassnames, configParser: TailwindConfigParser) {
this._configParser = configParser;
this._generatedClassNames = generatedClassnames;
}

Expand All @@ -22,6 +23,8 @@ export class FileContentGenerator {
'\n\n' +
this.allClassnamesTypesTemplate() +
'\n\n' +
this.utilityFunctionsTemplate() +
'\n\n' +
this.mainExportStatementsTemplate()
);
};
Expand All @@ -42,38 +45,56 @@ export class FileContentGenerator {
return "import classnamesLib from 'clsx';" + '\n' + `T_CUSTOM_CLASSES_IMPORT_STATEMENT`;
};

private allClassnamesTypesTemplate = (): string => {
const regularClassnames = this._generatedClassNames.regularClassnames;
const pseudoClassnames = this._generatedClassNames.pseudoClassnames;
// /**
// * Generates a type for pseudoclass variants
// */
// private variantsTypeTemplate = (): string => {
// const variants = this._configParser.getVariants();

// return this.generateTypesTemplate(
// 'PseudoClassVariants',
// variants.map(variant => variant + this._configParser.getSeparator()), // 'hover:', 'focus:'
// undefined,
// true,
// );
// };

const regularClassnamesTemplate = Object.keys(regularClassnames)
.map(classGroup => {
private allClassnamesTypesTemplate = (): string => {
const generatedClassnamesTemplate = Object.keys(this._generatedClassNames)
.map(classGroupKey => {
return this.generateTypesGroupTemplate(
regularClassnames[classGroup as keyof TAllClassnames] as TAllClassnames,
classGroup,
this._generatedClassNames[classGroupKey as keyof TAllClassnames] as TAllClassnames,
classGroupKey,
);
})
.join('\n');

const pseudoClassnamesTemplate = this.generateTypesTemplate({
typeName: 'PseudoClasses',
items: pseudoClassnames,
});
// TODO: do not generate this template
const allclassnamesExportTemplate = this.generateTypesTemplate(
'Classes',
Object.keys(this._generatedClassNames).map(x => 'T' + x),
undefined,
false,
);

const allclassnamesExportTemplate = this.generateTypesTemplate({
typeName: 'Classes',
items: Object.keys(regularClassnames)
.concat('PseudoClasses')
.map(x => 'T' + x),
}).replace(/'/g, ''); // TODO: REFACTOR this to use generateTypesGroupTemplate.
return generatedClassnamesTemplate + '\n\n' + allclassnamesExportTemplate;
};

return (
regularClassnamesTemplate +
'\n\n' +
pseudoClassnamesTemplate +
'\n\n' +
allclassnamesExportTemplate
);
private utilityFunctionsTemplate = (): string => {
return Object.keys(this._generatedClassNames)
.map(categoryGroupName => {
const categoryType = `T${categoryGroupName}`; // TTypography
// const categoryPseudoClassesTypes = '`${TPseudoClassVariants}:${' + categoryType + '}`';

return (
`type ${categoryType}Key = ${categoryType} | TTailwindString\n` +
`type ${categoryType}Arg = ${categoryType} | null | undefined | {[key in ${categoryType}Key]?: boolean} | TTailwindString\n` +
`type ${categoryType}UtilityFunction = (...args: ${categoryType}Arg[]) => TTailwindString\n` +
//prettier-ignore
`export const ${_.lowerFirst(categoryGroupName)}: ${categoryType}UtilityFunction = classnamesLib as any\n`
);
})
.join('\n');
};

private mainExportStatementsTemplate = (): string => {
Expand Down Expand Up @@ -132,11 +153,11 @@ export class FileContentGenerator {

const generateMembersStatements = (): string[] => {
return members.map(member => {
return this.generateTypesTemplate({
typeName: member,
items: group[member as keyof TAllClassnames] as string[],
prefix: this._configPrefix,
});
return this.generateTypesTemplate(
member,
group[member as keyof TAllClassnames] as string[],
this._configParser.getPrefix(),
);
});
};

Expand Down Expand Up @@ -172,14 +193,22 @@ export class FileContentGenerator {
* | foo
* | bar;
* ```
*
* or with quoutes:
* ```
* export type TBaz
* | 'foo'
* | 'bar';
* ```
* @param typeName The name of the type (without T prefix).
* @param items The list of the strings of items to add to the type name.
* @param prefix The prefix to add to the beginning of each item of the string array.
* @param surroundWithQuotes Whether to quote the types or not (make it a string or an actual type)
*/
private generateTypesTemplate = (
// prettier-ignore
{typeName, items, prefix}: {typeName: string; items: string[]; prefix?: string},
typeName: string,
items: string[],
prefix?: string,
surroundWithQuotes: boolean = true,
): string => {
return (
`export type T${_.upperFirst(typeName)} =` +
Expand All @@ -192,7 +221,9 @@ export class FileContentGenerator {
const shouldKeepDefaultSuffix: boolean = item.includes(x);
const name = shouldKeepDefaultSuffix ? item : item.replace('-DEFAULT', '');

return prefix ? `'${prefix}${name}'` : `'${name}'`;
const nameWithOrWithoutPrefix = `${prefix ? prefix : ''}${name}`;

return surroundWithQuotes ? `'${nameWithOrWithoutPrefix}'` : nameWithOrWithoutPrefix;
});
})
.join('\n | ')
Expand Down
5 changes: 0 additions & 5 deletions src/cli/types/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ export type Transforms = Record<TTransformsCategoryItem, string[]>;
export type TransitionsAndAnimations = Record<TTransitionsAndAnimationsCategoryItem, string[]>;
export type Typography = Record<TTypographyCategoryItem, string[]>;

export type TGeneratedClassnames = {
regularClassnames: TAllClassnames;
pseudoClassnames: string[];
};

export type TAllClassnames = {
Accessibility: Accessibility;
Backgrounds: Backgrounds;
Expand Down

0 comments on commit a8173c7

Please sign in to comment.