diff --git a/package.json b/package.json index 752d562b..e2697f5e 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "rollup-plugin-terser": "^7.0.2", "semver": "^7.3.2", "standard-version": "^9.1.0", - "tailwindcss": "^2.2.0", + "tailwindcss": "^3.0.0-alpha.1", "ts-jest": "~26.5.1", "typescript": "^4.3.4" } diff --git a/src/cli/core/ClassnamesGenerator.ts b/src/cli/core/ClassnamesGenerator.ts index 048d96d7..baefebb6 100644 --- a/src/cli/core/ClassnamesGenerator.ts +++ b/src/cli/core/ClassnamesGenerator.ts @@ -5,10 +5,11 @@ 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'; +import {regularClassGroupKeys} from './constants/regularClassGroupKeys'; /** * Responsible for generating the types from a parsed config by ConfigScanner. @@ -70,17 +71,12 @@ export class ClassnamesGenerator { /** * Get the generated classnames. */ - public generate = (): TGeneratedClassnames => { - return { - regularClassnames: this._generatedRegularClassnames, - pseudoClassnames: this._generatedPseudoClassnames, - }; + public generate = (): TAllClassnames => { + return this._generatedRegularClassnames; }; - private isJitModeEnabled = (): boolean => this._configParser.getMode() === 'jit'; - private layout = (): Layout | Record => { - const classnames = { + return { ...nonConfigurableClassNames.layout, objectPosition: Object.keys(this._theme.objectPosition).map(x => 'object-' + x), inset: Object.keys(this._theme.inset).flatMap(insetValue => { @@ -93,13 +89,8 @@ export class ClassnamesGenerator { zIndex: Object.keys(this._theme.zIndex).flatMap(zIndexValue => zIndexValue.startsWith('-') ? `-z-${zIndexValue.substring(1)}` : `z-${zIndexValue}`, ), + content: Object.keys(this._theme.content).map(x => 'content-' + x), }; - - if (this.isJitModeEnabled()) { - return {...classnames, content: Object.keys(this._theme.content).map(x => 'content-' + x)}; - } else { - return classnames; - } }; private backgrounds = (): Backgrounds => { @@ -117,7 +108,7 @@ export class ClassnamesGenerator { }; private borders = (): Borders | Record => { - const classnames = { + return { // Add all non configurable classes in `borders` plugin. // These are utilities that their names never change e.g. border styles (dashed, solid etc.) ...nonConfigurableClassNames.borders, @@ -133,7 +124,7 @@ export class ClassnamesGenerator { const sides = ['t', 'r', 'b', 'l']; return sides.map(side => `border-${side}-${width}`).concat(`border-${width}`); }), - + caretColor: this.generateClassesWithColors('caretColor'), /* Dynamic divide utilities */ divideColor: this.generateClassesWithColors('divideColor'), divideOpacity: this.getGeneratedClassesWithOpacities().divideOpacities, @@ -154,10 +145,6 @@ export class ClassnamesGenerator { ringOffsetColor: this.generateClassesWithColors('ringOffsetColor'), ringOffsetWidth: Object.keys(this._theme.ringOffsetWidth).map(x => 'ring-offset-' + x), }; - - return this.isJitModeEnabled() - ? {...classnames, caretColor: this.generateClassesWithColors('caretColor')} - : classnames; }; private tables = (): Tables => { @@ -388,30 +375,14 @@ export class ClassnamesGenerator { // and return them in a string array to be parsed and converted into a template string that // will be a part of the final generated file. See `FileContentGenerator` class. private pseudoClasses = (): string[] => { - // Initialise a pseudoclasses variable with empty array value. - const pseudoClasses: string[] = []; - // prettier-ignore - const allVariants = [ - 'responsive', 'motion-safe', 'motion-reduce', 'first', 'last', 'odd', 'even', 'visited', 'checked', - 'group-hover', 'group-focus', 'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled', - // Exhaustive pseudo-classess - 'only', 'first-of-type', 'last-of-type', 'only-of-type', 'target', 'default', 'indeterminate', - 'placeholder-shown', 'autofill', 'required', 'valid', 'invalid', 'in-range', 'out-of-range', - // New peer-*, selection & marker variants and before/after - 'peer-hover', 'peer-checked', 'peer-focus', 'selection', 'marker', 'before', 'after' - ]; - - // HACK: This block is just to make accessibility object align with other types object shape - const variantsConfig = Object.entries( - _.merge(this._configParser.getVariants(), { - screenReaders: this._configParser.getVariants().accessibility, - }), - ); + // Initialise a pseudoClasses array with base values. + const pseudoClasses: string[] = ['peer', 'group']; + if (this._darkMode === 'class') pseudoClasses.push('dark'); + + // Get the variants from config + const variants = this._configParser.getVariants(); - // For every key-value pair in the variants section in tailwind config... - // eslint-disable-next-line prefer-const - for (let [regularClassGroupKey, pseudoClassesVariantsForKey] of variantsConfig) { - // Find all matching names from the generated regular classes with the key of the variants config + for (const regularClassGroupKey of regularClassGroupKeys) { Object.keys(this._generatedRegularClassnames).map(key => { // If the current key is found to be a member of the generated regular classes group... if ( @@ -423,86 +394,22 @@ export class ClassnamesGenerator { `${key}.${regularClassGroupKey}`, ) as string[]; - // If JIT compiler mode is enabled... - if (this.isJitModeEnabled()) { - // Duplicate classnames with an important (!) prefix - const generatedClassGroupWithImportantPrefix = generatedClassGroup.map( - cls => '!' + cls, - ); - - // Append the classnames with important prefix to the regular classnames - generatedClassGroup = generatedClassGroup.concat( - generatedClassGroupWithImportantPrefix, - ); - - // Append the classnames with important prefix to the pseudo classes array - generatedClassGroupWithImportantPrefix.map(cls => pseudoClasses.push(cls)); - } + // Duplicate classnames with an important (!) prefix + const generatedClassGroupWithImportantPrefix = generatedClassGroup.map(cls => '!' + cls); + // Append the classnames with important prefix to the regular classnames + generatedClassGroup = generatedClassGroup.concat(generatedClassGroupWithImportantPrefix); + // Append the classnames with important prefix to the pseudo classes array + generatedClassGroupWithImportantPrefix.map(cls => pseudoClasses.push(cls)); // For every member of the found regular classes group... generatedClassGroup.map(classname => { - const isDarkModeEnabled = this._darkMode !== false; - - // If JIT compiler mode is enabled... - if (this.isJitModeEnabled()) { - // Enable all variants - pseudoClassesVariantsForKey = allVariants; - // Add 'peer' utility classname. used with peer-* classnames - pseudoClasses.push('peer'); - } - // Generate the classname of each variant... - pseudoClassesVariantsForKey.map(variant => { - if (variant === 'responsive') { - // Get the breakpoints from config - const [breakpoints] = this._configParser.getThemeProperty('screens'); - - // Create the classname for each breakpoint - breakpoints.map((breakpointVariant: string) => { - // Push the created classes to the pseudoClasses array - pseudoClasses.push( - breakpointVariant + this._separator + this._prefix + classname, - ); - - // Add stackable dark and responsive pseudoclasses if the key has both variants - if (pseudoClassesVariantsForKey.includes('dark') && isDarkModeEnabled) { - pseudoClasses.push( - breakpointVariant + - this._separator + - 'dark' + - this._separator + - this._prefix + - classname, - ); - } - }); - } - // Otherwise if the variant is 'dark' - else if (variant === 'dark') { - // If the dark mode is enabled... - if (isDarkModeEnabled) { - // Add the 'dark' prefix to the classname to create its pseudoclass - pseudoClasses.push(variant + this._separator + this._prefix + classname); - } - // Otherwise, do nothing. - } - // Otherwise... - else { - // Append the variant to the classname and push to the pseudoClasses array. - pseudoClasses.push(variant + this._separator + this._prefix + classname); - - // Add 'group' class if a the variant is group-hover, group-focus etc. - if (variant.startsWith('group') && !pseudoClasses.includes('group')) - pseudoClasses.push('group'); - - // Add 'dark' class if dark mode stategy is set to "class" - if (this._darkMode === 'class' && !pseudoClasses.includes('dark')) - pseudoClasses.push('dark'); - } + variants.map(variant => { + // Append the variant to the classname and push to the pseudoClasses array. + pseudoClasses.push(variant + this._separator + this._prefix + classname); }); }); } - // Otherwise, skip and do nothing }); } @@ -533,9 +440,9 @@ export class ClassnamesGenerator { if (typeof colorValue === 'object' && colorValue !== null) { // Loop over the deep objects and return the result for each key of the object. return Object.keys(colorValue).flatMap(shade => { - if (utilName === 'border' && this.isJitModeEnabled()) { + if (utilName === 'border') { return ['', 't', 'r', 'b', 'l'].map( - side => `${utilName}-${side}-${colorName}-${shade}`, + side => `${utilName}-${side.length > 0 ? side + '-' : ''}${colorName}-${shade}`, ); } else { return `${utilName}-${colorName}-${shade}`; @@ -545,7 +452,7 @@ export class ClassnamesGenerator { // Otherwise... else { // Return the result of merging the utility name with color value - if (utilName === 'border' && this.isJitModeEnabled()) { + if (utilName === 'border') { return ['', 't', 'r', 'b', 'l'].map( side => `${utilName}-${side.length > 0 ? side + '-' : ''}${colorName}`, ); @@ -555,17 +462,12 @@ export class ClassnamesGenerator { } }); - // Add the opacities short hand suffix `/{opacity}`: "bg-red-100/50" - const classnamesWithColorsAndOpacitySuffix = Object.keys( - this._configParser.getTheme().opacity, - ).flatMap(op => classnamesWithColors.map(cls => cls + '/' + op)); + // // Add the opacities short hand suffix `/{opacity}`: "bg-red-100/50" + // const classnamesWithColorsAndOpacitySuffix = Object.keys( + // this._configParser.getTheme().opacity, + // ).flatMap(op => classnamesWithColors.map(cls => cls + '/' + op)); - // Return the result classnames based on whether JIT mode is enabled or not - if (this.isJitModeEnabled()) { - return classnamesWithColors.concat(classnamesWithColorsAndOpacitySuffix); - } else { - return classnamesWithColors; - } + return classnamesWithColors; }; private getGeneratedClassesWithOpacities = (): ClassesWithOpacities => { diff --git a/src/cli/core/FileContentGenerator.ts b/src/cli/core/FileContentGenerator.ts index c9f7f4b2..9da19ae3 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 readonly _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; } @@ -20,7 +21,11 @@ export class FileContentGenerator { '\n\n' + this.importStatementsTemplate() + '\n\n' + - this.allClassnamesTypesTemplate() + + this.regularClassnamesTypesTemplate() + + '\n\n' + + this.variantsTypeTemplate() + + '\n\n' + + this.utilityFunctionsTemplate() + '\n\n' + this.mainExportStatementsTemplate() ); @@ -42,58 +47,92 @@ 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; + 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 regularClassnamesTypesTemplate = (): string => { + return 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, - }); + private utilityFunctionsTemplate = (): string => { + let template = + '//////////// Utility Function generic type\n\n' + + 'type TUtilityFunction = (\n' + + ' ...args: Array<\n' + + ' | T\n' + + ' | `!${T}`\n' + + ' | `${TPseudoClassVariants}${T}`\n' + + ' | `${TPseudoClassVariants}!${T}`\n' + + ' | null\n' + + ' | undefined\n' + + ' | {[key in T | `${TPseudoClassVariants}${T}` | `!${T}` | `${TPseudoClassVariants}!${T}` | TTailwindString]?: boolean}\n' + + ' | TTailwindString\n' + + ' >\n' + + ') => TTailwindString;'; + + for (const [categoryKey, value] of Object.entries(this._generatedClassNames)) { + const subCategoriesTemplate = Object.keys(value) // sub-ctegories keys + .map(SubCategory => { + const fnName = _.camelCase(SubCategory); + const fnType = `TUtilityFunction`; + + return `export const ${fnName}: ${fnType} = classnamesLib as any`; + }) + .join('\n'); - const allclassnamesExportTemplate = this.generateTypesTemplate({ - typeName: 'Classes', - items: Object.keys(regularClassnames) - .concat('PseudoClasses') - .map(x => 'T' + x), - }).replace(/'/g, ''); // TODO: REFACTOR this to use generateTypesGroupTemplate. + template = + template + + '\n' + + `\n//////////// ${categoryKey} Utility functions\n` + + '\n' + + subCategoriesTemplate; + } - return ( - regularClassnamesTemplate + - '\n\n' + - pseudoClassnamesTemplate + - '\n\n' + - allclassnamesExportTemplate - ); + return template; }; private mainExportStatementsTemplate = (): string => { + const utilityFunctionsObjectTemplate = Object.keys(this._generatedClassNames) + .map(cn => { + const subCategoryObj = this._generatedClassNames[cn as keyof TAllClassnames]; + if (subCategoryObj !== undefined) { + return Object.keys(subCategoryObj) + .map(sc => ' ' + sc) + .join(',\n'); + } + }) + .join(',\n'); + return ( - 'export type TTailwindString = "TAILWIND_STRING"\n' + + `export const TW = {\n${utilityFunctionsObjectTemplate}\n}\n` + '\n' + - 'export type TKey = TClasses | TTailwindStringIMPORTED_T_CUSTOM_CLASSES_KEY\n' + + 'export type TTailwindString = "TAILWIND_STRING"\n' + '\n' + 'export type TArg =\n' + - '| TClasses\n' + '| null\n' + '| undefined\n' + - '| {[key in TKey]?: boolean}\n' + '| TTailwindString\nIMPORTED_T_CUSTOM_CLASSES_ARG' + '\n' + 'export type TTailwind = (...args: TArg[]) => TTailwindString\n' + '\n' + - 'export const classnames: TTailwind = classnamesLib as any\n\n' + - 'export const tw = classnames\n\n' + - 'export default tw\n\n' + 'export const classnames: TTailwind = classnamesLib as any\n' + + '\n' + + 'export default classnames' ); }; @@ -132,11 +171,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 +211,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 +239,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/core/GeneratedFileWriter.ts b/src/cli/core/GeneratedFileWriter.ts index d4a126e1..62aab447 100644 --- a/src/cli/core/GeneratedFileWriter.ts +++ b/src/cli/core/GeneratedFileWriter.ts @@ -95,7 +95,7 @@ export class GeneratedFileWriter { // Create the file content from the generated classnames const fileContentTemplate = new FileContentGenerator( generatedClassnames, - configParser.getPrefix(), + configParser, ).generateFileContent(); // Resolve the custom classes import path relative to the output file diff --git a/src/cli/core/TailwindConfigParser.ts b/src/cli/core/TailwindConfigParser.ts index 348cc85d..51b7c2e4 100644 --- a/src/cli/core/TailwindConfigParser.ts +++ b/src/cli/core/TailwindConfigParser.ts @@ -1,12 +1,9 @@ import _ from 'lodash'; import {defaultTailwindConfig} from '../lib/defaultTailwindConfig'; -import { - TTailwindCSSConfig, - TConfigVariants, - TConfigDarkMode, - TConfigPlugins, -} from '../types/config'; +import {TTailwindCSSConfig, TConfigDarkMode, TConfigPlugins} from '../types/config'; import {TConfigTheme, TThemeItems} from '../types/config'; +import {baseVariants} from './constants/baseVariants'; +import {tailwindColors} from './constants/tailwindColors'; /* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return */ /** @@ -19,7 +16,6 @@ export class TailwindConfigParser { private readonly _darkMode: TConfigDarkMode; private readonly _themeConfig: TConfigTheme; private _evaluatedTheme: TConfigTheme | null; - private readonly _variantsConfig: TConfigVariants; private readonly _pluginsConfig: TConfigPlugins; constructor(tailwindConfig: TTailwindCSSConfig, plugins: TConfigPlugins) { @@ -31,19 +27,11 @@ export class TailwindConfigParser { this._separator = _.isEmpty(tailwindConfig.separator) ? ':' : (tailwindConfig.separator as string); - this._variantsConfig = _.isEmpty(tailwindConfig.variants) - ? defaultTailwindConfig.variants // Order does matter, defaultVariants will be overridden by themeVariants. - : {...defaultTailwindConfig.variants, ...tailwindConfig.variants}; this._themeConfig = {...defaultTailwindConfig.theme, ...tailwindConfig.theme}; this._evaluatedTheme = null; this._pluginsConfig = plugins; } - /** - * Gets the config mode value - */ - public getMode = (): string | undefined => this._mode; - /** * Gets the config prefix value */ @@ -126,29 +114,22 @@ export class TailwindConfigParser { }; /** - * Get config variants object + * Get the pseudoclass variants based on config. */ - public getVariants = (): Omit => { - // Get the `variants.extend` object - const variantsConfigExtend = this._variantsConfig?.extend; - - // If the variants.extend exists... - if (!!variantsConfigExtend) { - // Return the result of merging the variants with extend - return _.mergeWith( - this._variantsConfig, - variantsConfigExtend, - (variantsValues, variantsExtendValues) => { - if (_.isArray(variantsValues)) { - return variantsValues.concat(variantsExtendValues); - } - }, - ); - // Otherwise... - } else { - // Return the variants - return this._variantsConfig; - } + public getVariants = (): string[] => { + const variants = baseVariants; + + // get responsive variants + const [mediaBreakpoints] = this.getThemeProperty('screens'); + if (this.getDarkMode() == 'media') mediaBreakpoints.push('dark'); + + mediaBreakpoints.map((breakpoint: string) => { + if (!variants.includes(breakpoint)) { + variants.push(breakpoint); + } + }); + + return variants; }; /** @@ -176,7 +157,9 @@ class ThemeClosuresEvaluator { // If a value is a function... if (_.isFunction(value)) { // evaluate the value by running the evaluator methods in this class. - return value(this.makeThemePathResolver(valueSourceTheme || this.themeConfig), { + return value({ + colors: tailwindColors, + theme: this.makeThemePathResolver(valueSourceTheme || this.themeConfig), negative: ThemeClosuresEvaluator.negative.bind(this), breakpoints: ThemeClosuresEvaluator.breakpoints.bind(this), }); @@ -190,11 +173,11 @@ class ThemeClosuresEvaluator { /** * Creates evaluator for `theme()` functions/closures in config file */ - private makeThemePathResolver = (theme: Partial) => ( - path: string, - ): Record => { - return _.get(theme, _.trim(path, `'"`)) as Record | string>; - }; + private makeThemePathResolver = + (theme: Partial) => + (path: string): Record => { + return _.get(theme, _.trim(path, `'"`)) as Record | string>; + }; /** * Evaluate `negative()` functions/closures diff --git a/src/cli/core/constants/baseVariants.ts b/src/cli/core/constants/baseVariants.ts new file mode 100644 index 00000000..359a6f9b --- /dev/null +++ b/src/cli/core/constants/baseVariants.ts @@ -0,0 +1,46 @@ +export const baseVariants = [ + // 'responsive', + 'motion-safe', + 'motion-reduce', + 'first', + 'last', + 'odd', + 'even', + 'visited', + 'checked', + 'group', // + 'group-hover', + 'group-focus', + 'focus-within', + 'hover', + 'focus', + 'focus-visible', + 'active', + 'disabled', + // Exhaustive pseudo-classess + 'only', + 'first-of-type', + 'last-of-type', + 'only-of-type', + 'target', + 'default', + 'indeterminate', + 'placeholder-shown', + 'autofill', + 'required', + 'valid', + 'invalid', + 'in-range', + 'out-of-range', + // New peer-*, selection & marker variants and before/after + 'peer', // + 'peer-hover', + 'peer-checked', + 'peer-focus', + 'selection', + 'marker', + 'before', + 'after', + // dark mode utility + // 'dark', // +]; diff --git a/src/cli/core/constants/regularClassGroupKeys.ts b/src/cli/core/constants/regularClassGroupKeys.ts new file mode 100644 index 00000000..49ab4254 --- /dev/null +++ b/src/cli/core/constants/regularClassGroupKeys.ts @@ -0,0 +1,146 @@ +export const regularClassGroupKeys = [ + // 'accessibility', + 'screenReaders', + 'alignContent', + 'alignItems', + 'alignSelf', + 'animation', + 'appearance', + 'backdropBlur', + 'backdropBrightness', + 'backdropContrast', + 'backdropDropShadow', + 'backdropFilter', + 'backdropGrayscale', + 'backdropHueRotate', + 'backdropInvert', + 'backdropSaturate', + 'backdropSepia', + 'backgroundAttachment', + 'backgroundBlendMode', + 'backgroundClip', + 'backgroundColor', + 'backgroundImage', + 'backgroundOpacity', + 'backgroundPosition', + 'backgroundRepeat', + 'backgroundSize', + 'backgroundOrigin', + 'blur', + 'borderCollapse', + 'borderColor', + 'borderOpacity', + 'borderRadius', + 'borderStyle', + 'borderWidth', + 'boxDecorationBreak', + 'boxShadow', + 'boxSizing', + 'brightness', + 'clear', + 'container', + 'contrast', + 'cursor', + 'display', + 'divideColor', + 'divideOpacity', + 'divideStyle', + 'divideWidth', + 'dropShadow', + 'fill', + 'filter', + 'flex', + 'flexDirection', + 'flexGrow', + 'flexShrink', + 'flexWrap', + 'float', + 'fontFamily', + 'fontSize', + 'fontSmoothing', + 'fontStyle', + 'fontVariantNumeric', + 'fontWeight', + 'gap', + 'gradientColorStops', + 'grayscale', + 'gridAutoColumns', + 'gridAutoFlow', + 'gridAutoRows', + 'gridColumn', + 'gridColumnEnd', + 'gridColumnStart', + 'gridRow', + 'gridRowEnd', + 'gridRowStart', + 'gridTemplateColumns', + 'gridTemplateRows', + 'height', + 'hueRotate', + 'inset', + 'invert', + 'isolation', + 'justifyContent', + 'justifyItems', + 'justifySelf', + 'letterSpacing', + 'lineHeight', + 'listStylePosition', + 'listStyleType', + 'margin', + 'maxHeight', + 'maxWidth', + 'minHeight', + 'minWidth', + 'mixBlendMode', + 'objectFit', + 'objectPosition', + 'opacity', + 'order', + 'outline', + 'overflow', + 'overscrollBehavior', + 'padding', + 'placeContent', + 'placeItems', + 'placeSelf', + 'placeholderColor', + 'placeholderOpacity', + 'pointerEvents', + 'position', + 'resize', + 'ringColor', + 'ringOffsetColor', + 'ringOffsetWidth', + 'ringOpacity', + 'ringWidth', + 'rotate', + 'saturate', + 'scale', + 'sepia', + 'skew', + 'space', + 'stroke', + 'strokeWidth', + 'tableLayout', + 'textAlign', + 'textColor', + 'textDecoration', + 'textOpacity', + 'textOverflow', + 'textTransform', + 'transform', + 'transformOrigin', + 'transitionDelay', + 'transitionDuration', + 'transitionProperty', + 'transitionTimingFunction', + 'translate', + 'userSelect', + 'verticalAlign', + 'visibility', + 'whitespace', + 'width', + 'wordBreak', + 'zIndex', +]; diff --git a/src/cli/core/constants/tailwindColors.ts b/src/cli/core/constants/tailwindColors.ts new file mode 100644 index 00000000..b0e94d9e --- /dev/null +++ b/src/cli/core/constants/tailwindColors.ts @@ -0,0 +1,271 @@ +export const tailwindColors = { + inherit: 'inherit', + current: 'currentColor', + transparent: 'transparent', + black: '#000', + white: '#fff', + slate: { + 50: '#f8fafc', + 100: '#f1f5f9', + 200: '#e2e8f0', + 300: '#cbd5e1', + 400: '#94a3b8', + 500: '#64748b', + 600: '#475569', + 700: '#334155', + 800: '#1e293b', + 900: '#0f172a', + }, + gray: { + 50: '#f9fafb', + 100: '#f3f4f6', + 200: '#e5e7eb', + 300: '#d1d5db', + 400: '#9ca3af', + 500: '#6b7280', + 600: '#4b5563', + 700: '#374151', + 800: '#1f2937', + 900: '#111827', + }, + zinc: { + 50: '#fafafa', + 100: '#f4f4f5', + 200: '#e4e4e7', + 300: '#d4d4d8', + 400: '#a1a1aa', + 500: '#71717a', + 600: '#52525b', + 700: '#3f3f46', + 800: '#27272a', + 900: '#18181b', + }, + neutral: { + 50: '#fafafa', + 100: '#f5f5f5', + 200: '#e5e5e5', + 300: '#d4d4d4', + 400: '#a3a3a3', + 500: '#737373', + 600: '#525252', + 700: '#404040', + 800: '#262626', + 900: '#171717', + }, + stone: { + 50: '#fafaf9', + 100: '#f5f5f4', + 200: '#e7e5e4', + 300: '#d6d3d1', + 400: '#a8a29e', + 500: '#78716c', + 600: '#57534e', + 700: '#44403c', + 800: '#292524', + 900: '#1c1917', + }, + red: { + 50: '#fef2f2', + 100: '#fee2e2', + 200: '#fecaca', + 300: '#fca5a5', + 400: '#f87171', + 500: '#ef4444', + 600: '#dc2626', + 700: '#b91c1c', + 800: '#991b1b', + 900: '#7f1d1d', + }, + orange: { + 50: '#fff7ed', + 100: '#ffedd5', + 200: '#fed7aa', + 300: '#fdba74', + 400: '#fb923c', + 500: '#f97316', + 600: '#ea580c', + 700: '#c2410c', + 800: '#9a3412', + 900: '#7c2d12', + }, + amber: { + 50: '#fffbeb', + 100: '#fef3c7', + 200: '#fde68a', + 300: '#fcd34d', + 400: '#fbbf24', + 500: '#f59e0b', + 600: '#d97706', + 700: '#b45309', + 800: '#92400e', + 900: '#78350f', + }, + yellow: { + 50: '#fefce8', + 100: '#fef9c3', + 200: '#fef08a', + 300: '#fde047', + 400: '#facc15', + 500: '#eab308', + 600: '#ca8a04', + 700: '#a16207', + 800: '#854d0e', + 900: '#713f12', + }, + lime: { + 50: '#f7fee7', + 100: '#ecfccb', + 200: '#d9f99d', + 300: '#bef264', + 400: '#a3e635', + 500: '#84cc16', + 600: '#65a30d', + 700: '#4d7c0f', + 800: '#3f6212', + 900: '#365314', + }, + green: { + 50: '#f0fdf4', + 100: '#dcfce7', + 200: '#bbf7d0', + 300: '#86efac', + 400: '#4ade80', + 500: '#22c55e', + 600: '#16a34a', + 700: '#15803d', + 800: '#166534', + 900: '#14532d', + }, + emerald: { + 50: '#ecfdf5', + 100: '#d1fae5', + 200: '#a7f3d0', + 300: '#6ee7b7', + 400: '#34d399', + 500: '#10b981', + 600: '#059669', + 700: '#047857', + 800: '#065f46', + 900: '#064e3b', + }, + teal: { + 50: '#f0fdfa', + 100: '#ccfbf1', + 200: '#99f6e4', + 300: '#5eead4', + 400: '#2dd4bf', + 500: '#14b8a6', + 600: '#0d9488', + 700: '#0f766e', + 800: '#115e59', + 900: '#134e4a', + }, + cyan: { + 50: '#ecfeff', + 100: '#cffafe', + 200: '#a5f3fc', + 300: '#67e8f9', + 400: '#22d3ee', + 500: '#06b6d4', + 600: '#0891b2', + 700: '#0e7490', + 800: '#155e75', + 900: '#164e63', + }, + sky: { + 50: '#f0f9ff', + 100: '#e0f2fe', + 200: '#bae6fd', + 300: '#7dd3fc', + 400: '#38bdf8', + 500: '#0ea5e9', + 600: '#0284c7', + 700: '#0369a1', + 800: '#075985', + 900: '#0c4a6e', + }, + blue: { + 50: '#eff6ff', + 100: '#dbeafe', + 200: '#bfdbfe', + 300: '#93c5fd', + 400: '#60a5fa', + 500: '#3b82f6', + 600: '#2563eb', + 700: '#1d4ed8', + 800: '#1e40af', + 900: '#1e3a8a', + }, + indigo: { + 50: '#eef2ff', + 100: '#e0e7ff', + 200: '#c7d2fe', + 300: '#a5b4fc', + 400: '#818cf8', + 500: '#6366f1', + 600: '#4f46e5', + 700: '#4338ca', + 800: '#3730a3', + 900: '#312e81', + }, + violet: { + 50: '#f5f3ff', + 100: '#ede9fe', + 200: '#ddd6fe', + 300: '#c4b5fd', + 400: '#a78bfa', + 500: '#8b5cf6', + 600: '#7c3aed', + 700: '#6d28d9', + 800: '#5b21b6', + 900: '#4c1d95', + }, + purple: { + 50: '#faf5ff', + 100: '#f3e8ff', + 200: '#e9d5ff', + 300: '#d8b4fe', + 400: '#c084fc', + 500: '#a855f7', + 600: '#9333ea', + 700: '#7e22ce', + 800: '#6b21a8', + 900: '#581c87', + }, + fuchsia: { + 50: '#fdf4ff', + 100: '#fae8ff', + 200: '#f5d0fe', + 300: '#f0abfc', + 400: '#e879f9', + 500: '#d946ef', + 600: '#c026d3', + 700: '#a21caf', + 800: '#86198f', + 900: '#701a75', + }, + pink: { + 50: '#fdf2f8', + 100: '#fce7f3', + 200: '#fbcfe8', + 300: '#f9a8d4', + 400: '#f472b6', + 500: '#ec4899', + 600: '#db2777', + 700: '#be185d', + 800: '#9d174d', + 900: '#831843', + }, + rose: { + 50: '#fff1f2', + 100: '#ffe4e6', + 200: '#fecdd3', + 300: '#fda4af', + 400: '#fb7185', + 500: '#f43f5e', + 600: '#e11d48', + 700: '#be123c', + 800: '#9f1239', + 900: '#881337', + }, +}; diff --git a/src/cli/lib/non-configurable/typography.ts b/src/cli/lib/non-configurable/typography.ts index 3738e59c..9d32e4d0 100644 --- a/src/cli/lib/non-configurable/typography.ts +++ b/src/cli/lib/non-configurable/typography.ts @@ -22,7 +22,7 @@ const textDecoration = ['underline', 'line-through', 'no-underline']; const textTransform = ['uppercase', 'lowercase', 'capitalize', 'normal-case']; -const textOverflow = ['truncate', 'overflow-ellipsis', 'overflow-clip']; +const textOverflow = ['truncate', 'text-ellipsis', 'text-clip']; const verticalAlign = [ 'align-baseline', 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; diff --git a/src/cli/types/config.ts b/src/cli/types/config.ts index 722c68a8..03b8f698 100644 --- a/src/cli/types/config.ts +++ b/src/cli/types/config.ts @@ -1,3 +1,4 @@ +import {baseVariants} from '../core/constants/baseVariants'; import {defaultTailwindConfig} from '../lib/defaultTailwindConfig'; export type TTailwindCSSConfig = Partial< @@ -14,4 +15,4 @@ export type TConfigPlugins = Partial