@miyagi/core
Version:
miyagi is a component development tool for JavaScript template engines.
276 lines (243 loc) • 6.83 kB
JavaScript
/**
* Module for creating a menu object
* @module stateMenu
*/
import path from "path";
import getSourceStructure from "./structure.js";
import * as helpers from "../../helpers.js";
import { getMenu as getDocsMenu } from "../docs.js";
/**
* @param {object} directory - file tree object
* @returns {Array} file tree object of the component file in the given directory
*/
function getComponentFiles(directory) {
return directory.children.filter((child) => {
const baseName =
global.config.files.templates.name === "<component>"
? child.name.replace(`.${global.config.files.templates.extension}`, "")
: global.config.files.templates.name;
if (helpers.docFileIsIndexFile(child.path)) return true;
if (helpers.fileIsTemplateFile(child.name)) {
if (
global.config.files.templates.name === "<component>" &&
directory.name === baseName
)
return true;
if (global.config.files.templates.name === baseName) return true;
}
return false;
});
}
/**
* @param {object} directory - file tree object
* @returns {boolean} returns true if the given directory has a component file with the same name
*/
function hasComponentFileWithCorrectNameAsChild(directory) {
return (
directory.children &&
directory.children.length &&
getComponentFiles(directory).length > 0
);
}
/**
* @param {object} directory - file tree object
* @returns {object} adapted file tree object
*/
function getDataForLinkedDirectory(directory) {
const shortPath = helpers.getShortPathFromFullPath(directory.path);
const normalizedShortPath = helpers.normalizeString(shortPath);
const name = directory.name.replaceAll("-", " ");
return {
type: directory.type,
section: "components",
name,
fullPath: directory.path,
shortPath,
normalizedShortPath,
url: global.config.isBuild
? `/component-${normalizedShortPath}-embedded.html`
: `/component?file=${shortPath}&embedded=true`,
variations:
directory.variations.map((variation) => {
const normalizedName = helpers.normalizeString(variation.name);
return {
...variation,
normalizedName,
parentShortPath: shortPath,
url: global.config.isBuild
? `component-${normalizedShortPath}-variation-${normalizedName}-embedded.html`
: `/component?file=${shortPath}&variation=${encodeURIComponent(
variation.name,
)}&embedded=true`,
};
}) || [],
index: directory.index,
id: normalizedShortPath,
};
}
/**
* @param {object} file
* @returns {object}
*/
function getDataForDocumentationFile(file) {
const shortPath = helpers
.getShortPathFromFullPath(file.path)
.replace(".md", "");
const normalizedShortPath = helpers.normalizeString(shortPath);
return {
type: file.type,
name: path
.basename(file.name, ".md")
.replaceAll("-", " ")
.replaceAll("_", " "),
fullPath: file.path,
shortPath,
normalizedShortPath,
url: global.config.isBuild
? `/component-${normalizedShortPath}-embedded.html`
: `/component?file=${shortPath}&embedded=true`,
index: file.index,
id: normalizedShortPath,
};
}
/**
* @param {object} directory - file tree object
* @returns {object} adapted file tree object
*/
function getDataForDirectory(directory) {
const shortPath = path.relative(
path.join(process.cwd(), global.config.components.folder),
directory.path,
);
return {
type: directory.type,
name: directory.name.replaceAll("-", " "),
fullPath: directory.path,
shortPath,
index: directory.index,
id: helpers.normalizeString(shortPath),
};
}
/**
* @param {object} directory - file tree object
* @returns {object} adapted file tree object
*/
function restructureDirectory(directory) {
let item;
if (hasComponentFileWithCorrectNameAsChild(directory)) {
item = getDataForLinkedDirectory(directory);
} else {
item = getDataForDirectory(directory);
}
return item;
}
/**
* @param {object} item - file tree object
* @returns {boolean} returns true if the given file tree object has children
*/
function hasChildren(item) {
return item.children && item.children.length > 0;
}
/**
* @param {object} sourceTree
* @returns {object[]} array with adapted menu items
*/
export const getMenu = function (sourceTree) {
const srcStructure = getSourceStructure();
const arr = [];
let componentsMenu;
(function restructure(structure, array) {
for (const item of structure) {
if (item.type === "directory") {
const restructured = restructureDirectory(item);
if (hasChildren(item)) {
restructured.children = [];
restructure(item.children, restructured.children);
if (restructured.children.length === 0) {
delete restructured.children;
}
if (restructured.children) {
restructured.children.sort(function (a, b) {
const nameA = a.name.toLowerCase();
const nameB = b.name.toLowerCase();
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
return 0;
});
}
}
array.push(restructured);
} else if (
helpers.fileIsDocumentationFile(item.path) &&
!item.path.endsWith("index.md") &&
!item.path.endsWith("README.md") &&
path.basename(item.path, ".md") !==
path.dirname(item.path).split("/")[
path.dirname(item.path).split("/").length - 1
]
) {
array.push(getDataForDocumentationFile(item));
}
}
})(srcStructure, arr);
if (arr.length > 0) {
componentsMenu = {
topLevel: true,
section: "components",
name: "components",
type: "directory",
shortPath: "components",
file: null,
children: arr,
id: "components",
};
}
const docsMenu = getDocsMenu(sourceTree.docs);
const designTokensMenu = getDesignTokensMenu();
if (!docsMenu && !designTokensMenu && componentsMenu)
return componentsMenu.children;
const menus = [];
if (designTokensMenu) menus.push(designTokensMenu);
if (componentsMenu) menus.push(componentsMenu);
if (docsMenu) menus.push(docsMenu);
return menus;
};
/**
* @returns {object}
*/
function getDesignTokensMenu() {
if (global.config.assets.customProperties.files.length === 0) return null;
return {
topLevel: true,
name: "Design Tokens",
id: "design-tokens",
type: "directory",
shortPath: "design-tokens",
children: [
{
section: "design-tokens",
type: "file",
name: "colors",
url: global.config.isBuild
? "iframe-design-tokens-colors.html"
: "/iframe/design-tokens/colors",
},
{
section: "design-tokens",
type: "file",
name: "sizes",
url: global.config.isBuild
? "iframe-design-tokens-sizes.html"
: "/iframe/design-tokens/sizes",
},
{
section: "design-tokens",
type: "file",
name: "typography",
url: global.config.isBuild
? "iframe-design-tokens-typography.html"
: "/iframe/design-tokens/typography",
},
],
};
}