-
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
180 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "tailwindcss-classnames", | ||
"version": "1.2.2", | ||
"version": "1.2.3", | ||
"description": "Functional typed classnames for TailwindCSS", | ||
"author": "Christian Alfoni <[email protected]>", | ||
"contributors": [ | ||
|
@@ -21,7 +21,7 @@ | |
"build:lib": "tsc --outDir lib --module commonjs", | ||
"build:es": "tsc --outDir es --module es2015", | ||
"build:umd": "npm run build:es && rollup --config && dts-bundle --name dist/bundle --main es --outputAsModuleFolder", | ||
"clean": "rimraf dist es lib coverage", | ||
"clean": "rimraf dist es lib coverage tailwindcss-classnames.ts", | ||
"typecheck": "tsc --noEmit", | ||
"lint": "tslint --project tsconfig.json --format stylish", | ||
"format": "prettier '**/*.{md,js,jsx,json,ts,tsx}' --write", | ||
|
@@ -47,6 +47,7 @@ | |
], | ||
"dependencies": { | ||
"classnames": "^2.2.6", | ||
"commander": "^5.1.0", | ||
"inquirer": "^7.1.0", | ||
"lodash.isempty": "^4.4.0", | ||
"tslib": "^1.9.3" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,156 +1,48 @@ | ||
#!/usr/bin/env node | ||
|
||
/* tslint:disable:no-eval no-console */ | ||
import fs from 'fs'; | ||
import commander from 'commander'; | ||
import inquirer from 'inquirer'; | ||
import isEmpty from 'lodash.isempty'; | ||
|
||
import { baseTemplateString, defaultColors, defaultScreens, defaultSpacing, generateTypes } from './utils'; | ||
|
||
inquirer | ||
.prompt([ | ||
{ | ||
name: 'configFilename', | ||
type: 'input', | ||
default: 'tailwind.config.js', | ||
message: 'Tailwind configuration filename', | ||
}, | ||
{ | ||
name: 'outputFilename', | ||
type: 'input', | ||
default: 'tailwindcss-classnames.ts', | ||
message: 'Name of the file with generated types', | ||
}, | ||
]) | ||
.then(answers => { | ||
fs.readFile(`./${answers.configFilename}`, { encoding: 'utf-8' }, (err, data: any) => { | ||
if (err) { | ||
console.error(err); | ||
} | ||
|
||
data = data.replace(/('|")?plugins('|")? *: *\[(.*|\n)*?\],?/g, ''); | ||
|
||
const CONFIG = eval(data); | ||
const THEME_CONFIG = CONFIG.theme; | ||
const PREFIX_CONFIG = CONFIG.prefix; | ||
const SEPARATOR_CONFIG = CONFIG.separator; | ||
|
||
const prefix = isEmpty(PREFIX_CONFIG) ? '' : PREFIX_CONFIG; | ||
const separator = isEmpty(SEPARATOR_CONFIG) ? ':' : SEPARATOR_CONFIG; | ||
const themeColors = isEmpty(THEME_CONFIG?.colors) ? defaultColors : THEME_CONFIG?.colors; | ||
const extendedThemeColors = THEME_CONFIG?.extend?.colors; | ||
const AllColors = extendedThemeColors ? { ...themeColors, ...extendedThemeColors } : themeColors; | ||
|
||
const backgroundColors: string[] = []; | ||
const placeholderColors: string[] = []; | ||
const borderColors: string[] = []; | ||
const textColors: string[] = []; | ||
// theme: { | ||
// colors: { | ||
// colorkey: colorVal ( "#fff" | {light: "#fff", lighter: "#f0f0f0",...} ) | ||
// } | ||
// } | ||
const colors = Object.keys(AllColors); | ||
for (let i = 0; i < colors.length; i += 1) { | ||
const colorKey = colors[i]; | ||
const colorVal = AllColors[colorKey]; | ||
if (colorVal instanceof Object) { | ||
const colorVariants = Object.keys(colorVal); | ||
colorVariants.map((variant: string) => { | ||
if (variant === 'default') { | ||
variant = ''; | ||
} else { | ||
variant = `-${variant}`; | ||
} | ||
backgroundColors.push(`${prefix}bg-${colorKey}${variant}`); | ||
placeholderColors.push(`${prefix}placeholder-${colorKey}${variant}`); | ||
borderColors.push(`${prefix}border-${colorKey}${variant}`); | ||
textColors.push(`${prefix}text-${colorKey}${variant}`); | ||
}); | ||
} else { | ||
backgroundColors.push(`${prefix}bg-${colorKey}`); | ||
placeholderColors.push(`${prefix}placeholder-${colorKey}`); | ||
borderColors.push(`${prefix}border-${colorKey}`); | ||
textColors.push(`${prefix}text-${colorKey}`); | ||
} | ||
} | ||
|
||
const themeBreakpoints = isEmpty(THEME_CONFIG?.screens) ? defaultScreens : THEME_CONFIG?.screens; | ||
const extendedThemeBreakpoints = THEME_CONFIG?.extend?.screens; | ||
const breakpoints = extendedThemeBreakpoints | ||
? { ...themeBreakpoints, ...extendedThemeBreakpoints } | ||
: themeBreakpoints; | ||
|
||
const breakpointExportStatements: string[] = []; | ||
const breakpointCreateCustomParams: string[] = []; | ||
const breakpointCreateCustomReturns: string[] = []; | ||
const maxWidthByBreakpoints: string[] = []; | ||
|
||
Object.keys(breakpoints).map((breakpoint: string) => { | ||
breakpointExportStatements.push( | ||
`export const ${breakpoint}: TPseudoClass = className => ('${prefix}${breakpoint}${separator}' + className) as TTailwindString;`, | ||
); | ||
breakpointCreateCustomParams.push(`${breakpoint}: TPseudoClass<T>;`); | ||
breakpointCreateCustomReturns.push(`${breakpoint},`); | ||
maxWidthByBreakpoints.push(`${prefix}max-w-screen-${breakpoint}`); | ||
}); | ||
|
||
const themeSpacings = isEmpty(THEME_CONFIG?.spacing) ? defaultSpacing : THEME_CONFIG?.spacing; | ||
const extendedThemeSpacings = THEME_CONFIG?.extend?.spacing; | ||
const allSpacings = extendedThemeSpacings ? { ...themeSpacings, ...extendedThemeSpacings } : themeSpacings; | ||
|
||
const paddingSpacings: string[] = []; | ||
const marginSpacings: string[] = []; | ||
const widthSpacings: string[] = []; | ||
const heightSpacings: string[] = []; | ||
|
||
const sides = ['', 'y', 'x', 't', 'r', 'b', 'l']; | ||
|
||
sides.map(side => { | ||
paddingSpacings.push(`${prefix}p${side}-auto`); | ||
marginSpacings.push(`${prefix}m${side}-auto`); | ||
import { createFileWithGeneratedTypes } from './createFile'; | ||
|
||
commander | ||
.option('-c, --config <config>', 'Name of the TailwindCSS config file') | ||
.option('-o, --output <output>', 'Name of the file with the generated types', 'tailwindcss-classnames.ts') | ||
.action(({ config, output }) => { | ||
if (config) { | ||
createFileWithGeneratedTypes({ | ||
configFilename: config, | ||
outputFilename: output, | ||
}); | ||
|
||
Object.keys(allSpacings).map((spacing, i) => { | ||
widthSpacings.push(`${prefix}w-${spacing}`); | ||
heightSpacings.push(`${prefix}h-${spacing}`); | ||
sides.map(side => { | ||
paddingSpacings.push(`${prefix}p${side}-${spacing}`); | ||
marginSpacings.push(`${prefix}m${side}-${spacing}`); | ||
if (parseInt(spacing, 10) !== 0 && Object.values(allSpacings)[i] !== 0) { | ||
paddingSpacings.push(`${prefix}-p${side}-${spacing}`); | ||
marginSpacings.push(`${prefix}-m${side}-${spacing}`); | ||
} else { | ||
inquirer | ||
.prompt([ | ||
{ | ||
name: 'configFilename', | ||
type: 'input', | ||
default: 'tailwind.config.js', | ||
message: 'Tailwind configuration filename', | ||
}, | ||
{ | ||
name: 'outputFilename', | ||
type: 'input', | ||
default: 'tailwindcss-classnames.ts', | ||
message: 'Name of the file with generated types', | ||
}, | ||
]) | ||
.then(answers => { | ||
createFileWithGeneratedTypes({ | ||
configFilename: answers.configFilename, | ||
outputFilename: answers.outputFilename, | ||
}); | ||
}) | ||
.catch(error => { | ||
if (error.isTtyError) { | ||
console.error("Prompt couldn't be rendered in the current environment"); | ||
} else { | ||
console.error('Something went wrong with the prompt'); | ||
} | ||
}); | ||
}); | ||
|
||
const result = baseTemplateString | ||
.replace(/_PREFIX_/g, prefix) | ||
.replace(/_SEPARATOR_/g, separator) | ||
.replace(/MAX_WIDTH_BY_BREAKPOINTS/g, generateTypes(maxWidthByBreakpoints)) | ||
.replace(/BREAKPOINT_EXPORT_STATEMENTS/g, breakpointExportStatements.join('\n\n')) | ||
.replace(/BREAKPOINTS_CREATE_CUSTOM_PARAMS/g, breakpointCreateCustomParams.join('\n ')) | ||
.replace(/BREAKPOINTS_CREATE_CUSTOM_RETURNS/g, breakpointCreateCustomReturns.join('\n ')) | ||
.replace(/PADDINGS/g, generateTypes(paddingSpacings)) | ||
.replace(/MARGINS/g, generateTypes(marginSpacings)) | ||
.replace(/WIDTH_SPACINGS/g, generateTypes(widthSpacings)) | ||
.replace(/HEIGHT_SPACINGS/g, generateTypes(heightSpacings)) | ||
.replace(/BACKGROUND_COLORS/g, generateTypes(backgroundColors)) | ||
.replace(/PLACEHOLDER_COLORS/g, generateTypes(placeholderColors)) | ||
.replace(/BORDER_COLORS/g, generateTypes(borderColors)) | ||
.replace(/TEXT_COLORS/g, generateTypes(textColors)); | ||
|
||
fs.writeFile(`${answers.outputFilename}`, result, 'utf8', error => { | ||
if (error) { | ||
console.error(error); | ||
} | ||
}); | ||
}); | ||
}) | ||
.catch(error => { | ||
if (error.isTtyError) { | ||
console.error("Prompt couldn't be rendered in the current environment"); | ||
} else { | ||
console.error('Something went wrong with the prompt'); | ||
} | ||
}); | ||
|
||
commander.parse(process.argv); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* tslint:disable:no-eval no-console */ | ||
|
||
import fs from 'fs'; | ||
import isEmpty from 'lodash.isempty'; | ||
import { baseTemplateString, defaultColors, defaultScreens, defaultSpacing, generateTypes } from './utils'; | ||
|
||
interface IOptions { | ||
configFilename: string; | ||
outputFilename: string; | ||
} | ||
|
||
export function createFileWithGeneratedTypes({ configFilename, outputFilename }: IOptions) { | ||
fs.readFile(`./${configFilename}`, { encoding: 'utf-8' }, (err, data: any) => { | ||
if (err) { | ||
console.error(err); | ||
} | ||
|
||
data = data.replace(/('|")?plugins('|")? *: *\[(.*|\n)*?\],?/g, ''); | ||
|
||
const CONFIG = eval(data); | ||
const THEME_CONFIG = CONFIG.theme; | ||
const PREFIX_CONFIG = CONFIG.prefix; | ||
const SEPARATOR_CONFIG = CONFIG.separator; | ||
|
||
const prefix = isEmpty(PREFIX_CONFIG) ? '' : PREFIX_CONFIG; | ||
const separator = isEmpty(SEPARATOR_CONFIG) ? ':' : SEPARATOR_CONFIG; | ||
const themeColors = isEmpty(THEME_CONFIG?.colors) ? defaultColors : THEME_CONFIG?.colors; | ||
const extendedThemeColors = THEME_CONFIG?.extend?.colors; | ||
const AllColors = extendedThemeColors ? { ...themeColors, ...extendedThemeColors } : themeColors; | ||
|
||
const backgroundColors: string[] = []; | ||
const placeholderColors: string[] = []; | ||
const borderColors: string[] = []; | ||
const textColors: string[] = []; | ||
// theme: { | ||
// colors: { | ||
// colorkey: colorVal ( "#fff" | {light: "#fff", lighter: "#f0f0f0",...} ) | ||
// } | ||
// } | ||
const colors = Object.keys(AllColors); | ||
for (let i = 0; i < colors.length; i += 1) { | ||
const colorKey = colors[i]; | ||
const colorVal = AllColors[colorKey]; | ||
if (colorVal instanceof Object) { | ||
const colorVariants = Object.keys(colorVal); | ||
colorVariants.map((variant: string) => { | ||
variant = variant === 'default' ? '' : `-${variant}`; | ||
backgroundColors.push(`${prefix}bg-${colorKey}${variant}`); | ||
placeholderColors.push(`${prefix}placeholder-${colorKey}${variant}`); | ||
borderColors.push(`${prefix}border-${colorKey}${variant}`); | ||
textColors.push(`${prefix}text-${colorKey}${variant}`); | ||
}); | ||
} else { | ||
backgroundColors.push(`${prefix}bg-${colorKey}`); | ||
placeholderColors.push(`${prefix}placeholder-${colorKey}`); | ||
borderColors.push(`${prefix}border-${colorKey}`); | ||
textColors.push(`${prefix}text-${colorKey}`); | ||
} | ||
} | ||
|
||
const themeBreakpoints = isEmpty(THEME_CONFIG?.screens) ? defaultScreens : THEME_CONFIG?.screens; | ||
const extendedThemeBreakpoints = THEME_CONFIG?.extend?.screens; | ||
const breakpoints = extendedThemeBreakpoints | ||
? { ...themeBreakpoints, ...extendedThemeBreakpoints } | ||
: themeBreakpoints; | ||
|
||
const breakpointExportStatements: string[] = []; | ||
const breakpointCreateCustomParams: string[] = []; | ||
const breakpointCreateCustomReturns: string[] = []; | ||
const maxWidthByBreakpoints: string[] = []; | ||
|
||
Object.keys(breakpoints).map((breakpoint: string) => { | ||
breakpointExportStatements.push( | ||
`export const ${breakpoint}: TPseudoClass = className => ('${prefix}${breakpoint}${separator}' + className) as TTailwindString;`, | ||
); | ||
breakpointCreateCustomParams.push(`${breakpoint}: TPseudoClass<T>;`); | ||
breakpointCreateCustomReturns.push(`${breakpoint},`); | ||
maxWidthByBreakpoints.push(`${prefix}max-w-screen-${breakpoint}`); | ||
}); | ||
|
||
const themeSpacings = isEmpty(THEME_CONFIG?.spacing) ? defaultSpacing : THEME_CONFIG?.spacing; | ||
const extendedThemeSpacings = THEME_CONFIG?.extend?.spacing; | ||
const allSpacings = extendedThemeSpacings ? { ...themeSpacings, ...extendedThemeSpacings } : themeSpacings; | ||
|
||
const paddingSpacings: string[] = []; | ||
const marginSpacings: string[] = []; | ||
const widthSpacings: string[] = []; | ||
const heightSpacings: string[] = []; | ||
|
||
const sides = ['', 'y', 'x', 't', 'r', 'b', 'l']; | ||
|
||
sides.map(side => { | ||
paddingSpacings.push(`${prefix}p${side}-auto`); | ||
marginSpacings.push(`${prefix}m${side}-auto`); | ||
}); | ||
|
||
Object.keys(allSpacings).map((spacing, i) => { | ||
widthSpacings.push(`${prefix}w-${spacing}`); | ||
heightSpacings.push(`${prefix}h-${spacing}`); | ||
sides.map(side => { | ||
paddingSpacings.push(`${prefix}p${side}-${spacing}`); | ||
marginSpacings.push(`${prefix}m${side}-${spacing}`); | ||
if (parseInt(spacing, 10) !== 0 && Object.values(allSpacings)[i] !== 0) { | ||
paddingSpacings.push(`${prefix}-p${side}-${spacing}`); | ||
marginSpacings.push(`${prefix}-m${side}-${spacing}`); | ||
} | ||
}); | ||
}); | ||
|
||
const result = baseTemplateString | ||
.replace(/_PREFIX_/g, prefix) | ||
.replace(/_SEPARATOR_/g, separator) | ||
.replace(/MAX_WIDTH_BY_BREAKPOINTS/g, generateTypes(maxWidthByBreakpoints)) | ||
.replace(/BREAKPOINT_EXPORT_STATEMENTS/g, breakpointExportStatements.join('\n\n')) | ||
.replace(/BREAKPOINTS_CREATE_CUSTOM_PARAMS/g, breakpointCreateCustomParams.join('\n ')) | ||
.replace(/BREAKPOINTS_CREATE_CUSTOM_RETURNS/g, breakpointCreateCustomReturns.join('\n ')) | ||
.replace(/PADDINGS/g, generateTypes(paddingSpacings)) | ||
.replace(/MARGINS/g, generateTypes(marginSpacings)) | ||
.replace(/WIDTH_SPACINGS/g, generateTypes(widthSpacings)) | ||
.replace(/HEIGHT_SPACINGS/g, generateTypes(heightSpacings)) | ||
.replace(/BACKGROUND_COLORS/g, generateTypes(backgroundColors)) | ||
.replace(/PLACEHOLDER_COLORS/g, generateTypes(placeholderColors)) | ||
.replace(/BORDER_COLORS/g, generateTypes(borderColors)) | ||
.replace(/TEXT_COLORS/g, generateTypes(textColors)); | ||
|
||
fs.writeFile(`${outputFilename}`, result, 'utf8', error => { | ||
if (error) { | ||
console.error(error); | ||
} | ||
}); | ||
}); | ||
} |