From a8173c75c9c03a8843fbdccd4c8f82751e47fef3 Mon Sep 17 00:00:00 2001 From: Muhammad Sammy Date: Fri, 22 Oct 2021 20:37:40 +0200 Subject: [PATCH] feat: generate utility function for all category types ( #293) --- src/cli/core/ClassnamesGenerator.ts | 9 +-- src/cli/core/FileContentGenerator.ts | 107 +++++++++++++++++---------- src/cli/types/classes.ts | 5 -- 3 files changed, 72 insertions(+), 49 deletions(-) diff --git a/src/cli/core/ClassnamesGenerator.ts b/src/cli/core/ClassnamesGenerator.ts index 14be9394..a043944a 100644 --- a/src/cli/core/ClassnamesGenerator.ts +++ b/src/cli/core/ClassnamesGenerator.ts @@ -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'; @@ -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 => { diff --git a/src/cli/core/FileContentGenerator.ts b/src/cli/core/FileContentGenerator.ts index c9f7f4b2..8a6e5961 100644 --- a/src/cli/core/FileContentGenerator.ts +++ b/src/cli/core/FileContentGenerator.ts @@ -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; } @@ -22,6 +23,8 @@ export class FileContentGenerator { '\n\n' + this.allClassnamesTypesTemplate() + '\n\n' + + this.utilityFunctionsTemplate() + + '\n\n' + this.mainExportStatementsTemplate() ); }; @@ -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 => { @@ -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(), + ); }); }; @@ -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)} =` + @@ -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 | ') diff --git a/src/cli/types/classes.ts b/src/cli/types/classes.ts index 2c3b08f9..cbc5b9fe 100644 --- a/src/cli/types/classes.ts +++ b/src/cli/types/classes.ts @@ -17,11 +17,6 @@ export type Transforms = Record; export type TransitionsAndAnimations = Record; export type Typography = Record; -export type TGeneratedClassnames = { - regularClassnames: TAllClassnames; - pseudoClassnames: string[]; -}; - export type TAllClassnames = { Accessibility: Accessibility; Backgrounds: Backgrounds;