Skip to content

Commit

Permalink
feat(utils): formatTree utility (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
Barbapapazes authored Dec 1, 2023
1 parent e3be6f6 commit ce2b368
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 0 deletions.
89 changes: 89 additions & 0 deletions examples/tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { TreeItem, formatTree } from "../src/utils/tree";
import { consola } from "./utils";

function main() {
const keywords = [
"console",
"logger",
"reporter",
"elegant",
"cli",
"universal",
"unified",
"prompt",
"clack",
"format",
"error",
"stacktrace",
];

consola.log(formatTree(keywords));

consola.log(
formatTree(keywords, {
color: "cyan",
prefix: " | ",
}),
);

consola.log(
formatTree(
[
{
text: "consola",
color: "green",
},
{
text: "logger",
},
].map(
(item) =>
({
text: ` ${item.text}`,
color: item.color,
}) as TreeItem,
),
{
color: "gray",
},
),
);

// Deep tree
consola.log(
formatTree([
{
text: "format",
color: "red",
},
{
text: "consola",
color: "yellow",
children: [
{
text: "logger",
color: "green",
children: [
{
text: "reporter",
color: "cyan",
},
{
text: "test",
color: "magenta",
children: ["nice tree"],
},
],
},
{
text: "reporter",
color: "bold",
},
"test",
],
},
]),
);
}

main();
76 changes: 76 additions & 0 deletions src/utils/tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { type ColorName, colorize } from "./color";

export type TreeItemObject = {
/**
* Text of the item
*/
text: string;

/**
* Children of the item
*/
children?: TreeItem[];

/**
* Color of the item
*/
color?: ColorName;
};

export type TreeItem = string | TreeItemObject;

export type TreeOptions = {
/**
* Color of the tree
*/
color?: ColorName;

/**
* Prefix of the tree
*
* @default " "
*/
prefix?: string;
};

export function formatTree(items: TreeItem[], options?: TreeOptions): string {
options = {
prefix: " ",
...options,
};

const tree = _buildTree(items, options).join("");
if (options && options.color) {
return colorize(options.color, tree);
}

return tree;
}

function _buildTree(items: TreeItem[], options?: TreeOptions): string[] {
const chunks: string[] = [];

const total = items.length - 1;
for (let i = 0; i <= total; i++) {
const item = items[i];
const isLast = i === total;
const prefix = isLast ? `${options?.prefix}└─` : `${options?.prefix}├─`;

if (typeof item === "string") {
chunks.push(`${prefix}${item}\n`);
} else {
const log = `${prefix}${item.text}\n`;
chunks.push(item.color ? colorize(item.color, log) : log);

if (item.children) {
const _tree = _buildTree(item.children, {
...options,
prefix: `${options?.prefix}${isLast ? " " : "│ "}`,
});
chunks.push(..._tree);
}
}
}

return chunks;
}

0 comments on commit ce2b368

Please sign in to comment.