Skip to content

Commit

Permalink
feat(create-chakra-icons): ability to set output specific #10 (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
r17x committed Feb 3, 2022
1 parent 8323cb5 commit 091f679
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 15 deletions.
7 changes: 7 additions & 0 deletions packages/create-chakra-icons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ create-chakra-icons [FLAGS] [OPTIONS] [INPUT]
-P, --prefix <STRING> Sets for prefix in export named declaration.
[e.g.: -S "Icon"]
--ts, --typescript Sets output as TypeScript code.

-T, --type <TYPE> TYPE:
(F|f). Sets output code with function \`createIcon({...})\`.
(C|c). Sets output code with Component Icon \`(props) => <Icon> {...} </Icon>\`.

[e.g.: -T C]

```

### Input
Expand Down
41 changes: 35 additions & 6 deletions packages/create-chakra-icons/lib/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
const t = require("@babel/types");
const toBabelAST = require("@svgr/hast-util-to-babel-ast");
const { pairsToObject, objectToPairs } = require("./utils");

const toLiteral = (val) =>
({
[typeof val === "string"]: () => t.stringLiteral(val),
[typeof val === "number"]: () => t.numericLiteral(val),
[Array.isArray(val)]: () => t.arrayExpression(val.map((v) => toLiteral(v))),
[t.isLiteral(val) || t.isArrayExpression(val)]: () => val,
// TODO: handle more type
}.true());

/**
* @memberof ast
* @name pairToObjectProperty
Expand All @@ -26,12 +36,7 @@ const { pairsToObject, objectToPairs } = require("./utils");
*
*
*/
const pairToObjectProperty = ([key, value]) =>
t.objectProperty(
t.identifier(key),
// TODO check when value is not string
t.stringLiteral(value),
);
const pairToObjectProperty = ([key, value]) => t.objectProperty(t.identifier(key), toLiteral(value));
/**
* @memberof ast
* @name objectPropertyToPair
Expand Down Expand Up @@ -174,6 +179,29 @@ const hastToProperties = ({
viewBox,
d,
});
/**
* @param {Object}
* @return {Object}
*/
const hastToProperties2 = ({
children: [
{
properties: { viewBox },
children,
},
],
}) => {
const expressions = children
.map((v) => toBabelAST({ type: "root", children: [v] }))
.flatMap((v) => v.body)
.map((v) => v.expression);
const path = t.arrayExpression(expressions);

return {
viewBox,
path,
};
};

/**
* @memberof ast
Expand Down Expand Up @@ -258,6 +286,7 @@ module.exports = {
toExportNamedDeclaration,
toSource,
hastToProperties,
hastToProperties2,
hastToJSXProperties,
hastChildrenLength,
hastToComponent,
Expand Down
12 changes: 9 additions & 3 deletions packages/create-chakra-icons/lib/chakra.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const ast = require("./ast");
const createChakraIcon = (...sources) => {
// eslint-disable-next-line no-shadow
const isTypescript = sources.some(({ isTypescript }) => isTypescript);
const perFileCode = ({ source: svg, displayName }) => {
const perFileCode = ({ source: svg, displayName, outputType }) => {
const hast = SvgParser.parse(svg);
// This for solve issue {https://github.com/kodingdotninja/create-chakra-icons/issues/7}
// In the issue 7, have some example svg file at examples/issue7.svg
Expand All @@ -38,11 +38,16 @@ const createChakraIcon = (...sources) => {
}
return false;
})();
if (ast.hastChildrenLength(hast) > 1 || isNotTagnamePath) {

const outputWithCreateIcon = outputType.toLowerCase() === "f";

const outputWithIcon = outputType.toLowerCase() === "c" || ast.hastChildrenLength(hast) > 1 || isNotTagnamePath;

if (outputWithIcon && !outputWithCreateIcon) {
return ast.hastToComponent(hast, { displayName, isTypescript });
}

const properties = ast.hastToProperties(hast);
const properties = outputWithIcon ? ast.hastToProperties2(hast) : ast.hastToProperties(hast);

const objectExpression = ast.objectToObjectExpression({
displayName,
Expand All @@ -53,6 +58,7 @@ const createChakraIcon = (...sources) => {
displayName,
objectExpression: [objectExpression],
});

return iconAST;
};
const svgCodes = [...sources].map(perFileCode);
Expand Down
32 changes: 26 additions & 6 deletions packages/create-chakra-icons/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ const { createChakraIcon } = require("./chakra");
const { stringToCase, compose } = require("./utils");
const { stdout: output, stdin: input, exit, stderr: error } = require("process");

const encoding = "utf-8";
const ENCODING = "utf-8";

function pipeline(args) {
input.setEncoding(encoding);
input.setEncoding(ENCODING);
input.on("data", (data) => {
if (data) {
const { name, exportNameCase, exportNameSuffix, exportNamePrefix, isTypescript, outputFile } =
const { name, exportNameCase, exportNameSuffix, exportNamePrefix, isTypescript, outputFile, outputType } =
getCommonOptions(args);
const exportNamed = createExportNamed(exportNameCase, exportNamePrefix, exportNameSuffix);
const source = createCode({
Expand All @@ -23,6 +23,7 @@ function pipeline(args) {
isTypescript,
exportNameSuffix,
exportNamePrefix,
outputType,
});
return outputFile
? Fs.writeFile(Path.resolve(outputFile), source, (err) => {
Expand All @@ -37,7 +38,7 @@ function pipeline(args) {
}

function main(args) {
const { inputs, outputFile, name, exportNameCase, exportNameSuffix, exportNamePrefix, isTypescript } =
const { inputs, outputFile, name, exportNameCase, exportNameSuffix, exportNamePrefix, isTypescript, outputType } =
getCommonOptions(args);
const version = args.V || args.version;

Expand All @@ -48,10 +49,11 @@ function main(args) {
stringToInput({
displayName: name,
exportNameCase,
encoding,
encoding: ENCODING,
isTypescript,
exportNameSuffix,
exportNamePrefix,
outputType,
}),
[],
),
Expand Down Expand Up @@ -93,8 +95,15 @@ OPTIONS:
-P, --prefix <STRING> Sets for prefix in export named declaration.
[e.g.: -S "Icon"]
--ts, --typescript Sets output as TypeScript code.
-T, --type <TYPE> TYPE:
(F|f). Sets output code with function \`createIcon({...})\`.
(C|c). Sets output code with Component Icon \`(props) => <Icon> {...} </Icon>\`.
[e.g.: -T C]
[INPUT]: This option for read the input from PATH of FILE or DIRECTORIES.
[e.g.: create-chakra-icons ./MyICON.svg ~/assets]
Expand All @@ -113,6 +122,7 @@ function getCommonOptions(args) {
exportNameCase: args.C || args.case,
exportNameSuffix: args.S || args.suffix || "",
exportNamePrefix: args.P || args.prefix || "",
outputType: String(args.T || args.type),
};
}

Expand All @@ -125,7 +135,15 @@ function createExportNamed(exportNameCase, exportNamePrefix, exportNameSuffix) {
}

// eslint-disable-next-line no-shadow
function stringToInput({ displayName, exportNameCase, exportNamePrefix, exportNameSuffix, encoding, isTypescript }) {
function stringToInput({
displayName,
exportNameCase,
exportNamePrefix,
exportNameSuffix,
encoding,
isTypescript,
outputType,
}) {
const exportNamed = createExportNamed(exportNameCase, exportNamePrefix, exportNameSuffix);

return (acc, str) => {
Expand All @@ -140,13 +158,15 @@ function stringToInput({ displayName, exportNameCase, exportNamePrefix, exportNa
displayName: exportNamed(Path.basename(source).split(".")[0]),
source: Fs.readFileSync(source, encoding),
isTypescript,
outputType,
})),
);
} else {
acc.push({
displayName: exportNamed(displayName),
source: Fs.readFileSync(str, encoding),
isTypescript,
outputType,
});
}
}
Expand Down

0 comments on commit 091f679

Please sign in to comment.