UNPKG

igniteui-sassdoc-theme

Version:

Default SassDoc theme used in Ignite UI for Angular.

311 lines (254 loc) 8.24 kB
import type { Context, Data, Item, GroupedData, GroupedItems, } from "../content/sassdoc-schema"; /** * Processes group names in the Context. * First applies the standard extras.groupName function, then * replaces group slugs with their display names for each item. * * @param ctx - The Context to process */ export function groupName(ctx: Context): void { if (!ctx.data) return; ctx.groups = ctx.groups || {}; ctx.groupDescriptions = ctx.groupDescriptions || {}; for (const slug of Object.keys(ctx.groups)) { if (ctx.groups) { ctx.groups[slug.toLowerCase()] = ctx.groups[slug]; } } for (const item of ctx.data) { if (!item.group || item.group.length === 0) continue; const group: Record<string, string> = {}; const processedGroups: string[] = []; for (const slug of item.group) { const lowerSlug = slug.toLowerCase(); if (ctx.groups && lowerSlug in ctx.groups) { group[lowerSlug] = ctx.groups[lowerSlug]; } else if (ctx.groups) { group[lowerSlug] = ctx.groups[lowerSlug] = lowerSlug; } const displayName = group[lowerSlug]; if (displayName) { processedGroups.push(displayName); } } if (item.groupDescriptions && ctx.groupDescriptions) { Object.assign(ctx.groupDescriptions, item.groupDescriptions); } item.groupName = group; if (processedGroups.length > 0) { item.group = processedGroups; } } } /** * Processes a require item to add group and name information */ function processRequireItem(items: Map<string, string>, req: any) { const { item, ...plainReq } = req; if (!plainReq.external && plainReq.name) { const group = items.get(plainReq.name); if (group) { plainReq.group = group; plainReq.name = item.name ?? plainReq.name; } } return plainReq; } /** * Processes a referecne item to add group and name information */ function processReferenceItem( items: Map<string, string>, item: Pick<Item, "context" | "description" | "name">, ) { const { context, description, name } = item; const plainItem = { description, context, group: "", name: "" }; if (context?.name) { const group = items.get(context.name); if (group) { plainItem.group = group; plainItem.name = name ?? context.name; } } return plainItem; } /** * Processes a reference to a group with an alias, returning the aliased item if found. * If the aliased item exists in the context data, returns an object with its name and the provided group. * Otherwise, returns the original reference. * * @param ctx - The context containing data to search for the aliased item. * @param ref - An object containing the name to search for and the group array. * @returns An object with the resolved name and group. */ function processAliasedGroup( ctx: Context, ref: { name: string; group: string[] }, ) { const aliasedItem = ctx.data.find((item) => item.context.name === ref.name); if (aliasedItem) { return { name: aliasedItem.name ?? aliasedItem.context.name, group: ref.group, }; } return ref; } /** * Resolves an alias to its corresponding item's name within the context data. * If the alias is found, returns the item's name; otherwise, returns the alias itself. * * @param ctx - The context containing the data array. * @param alias - The alias string to resolve. * @returns The resolved name or the original alias if not found. */ function processAliased(ctx: Context, alias: string) { const aliasedItem = ctx.data.find((item) => item.context.name === alias); return aliasedItem?.name ?? alias; } /** * Resolves the name of the item that the given item is an alias of. * If the referenced item is found, returns its name; otherwise, returns the alias value. * * @param ctx - The context containing the data array. * @param item - The item whose alias is to be resolved. * @returns The resolved name or the original alias if not found. */ function processAliasOf(ctx: Context, item: Item) { const itemAlias = ctx.data.find((_item) => { return _item.context.name === item.alias; }); return (itemAlias && itemAlias.name) ?? item.alias; } /** * Enriches cross-references between items with group information. * Processes various types of references (require, usedBy, see, aliased) to ensure * they contain appropriate group data for navigation and display. * * @param ctx - The context containing the data to process. */ export function enrichCrossReferences(ctx: Context): void { if (!ctx.data) return; const itemToGroup = new Map<string, string>(); for (const item of ctx.data) { if (item.context?.name && Array.isArray(item.group)) { itemToGroup.set(item.context.name, item.group[0]); } } for (const item of ctx.data) { if (item.require && Array.isArray(item.require)) { item.require = item.require.map((_item) => processRequireItem(itemToGroup, _item), ); } if (item.usedBy && Array.isArray(item.usedBy)) { item.usedBy = item.usedBy.map((_item) => processReferenceItem(itemToGroup, _item), ); } if (item.see && Array.isArray(item.see)) { item.see = item.see.map((_item) => processReferenceItem(itemToGroup, _item), ); } if (item.aliased && Array.isArray(item.aliased)) { item.aliased = item.aliased.map((alias) => processAliased(ctx, alias)); } if (item.aliasedGroup && Array.isArray(item.aliasedGroup)) { item.aliasedGroup = item.aliasedGroup.map((_item) => processAliasedGroup(ctx, _item), ); } if (item.alias) { item.alias = processAliasOf(ctx, item); } } } /** * Groups items by their group and type */ function groupItems(data: Data): Record<string, Record<string, Item[]>> { const result: Record<string, Record<string, Item[]>> = Object.create(null); for (const item of data) { const group = item.group?.[0]; const type = item.context?.type; if (group === undefined || type === undefined) { continue; } if (!Object.prototype.hasOwnProperty.call(result, group)) { result[group] = Object.create(null); } if (!Object.prototype.hasOwnProperty.call(result[group], type)) { result[group][type] = []; } result[group][type].push(item); } return result; } /** * Sorts grouped items by type according to specified order */ function sortByType( groupedData: Record<string, Record<string, Item[]>>, ): GroupedData { const typeOrder: Record<string, number> = { placeholder: 1, variable: 2, function: 3, mixin: 4, }; const sortedResult: GroupedData = Object.create(null); for (const group in groupedData) { sortedResult[group] = {} as GroupedItems; const types = Object.keys(groupedData[group]); types.sort((a, b) => { const orderA = typeOrder[a] || Number.MAX_SAFE_INTEGER; const orderB = typeOrder[b] || Number.MAX_SAFE_INTEGER; return orderA - orderB; }); for (const type of types) { (sortedResult[group] as Record<string, Item[]>)[type] = groupedData[group][type]; } } return sortedResult; } /** * Groups items by their group and type, then sorts the types * in order: placeholder, variable, function, mixin * * @param data - The SassDoc context data * @returns Grouped and sorted data */ export function byGroupAndType(data: Data): GroupedData { const grouped = groupItems(data); return sortByType(grouped); } /** * Adds a `display` property for each data item based on display configuration * (hide private items and aliases for example). * * @param ctx - The SassDoc context object */ export function display(ctx: Context): void { if (!ctx.display) { return; } ctx.data = ctx.data.filter((item: Item) => { const displayItemAccess = ctx.display?.access ? ctx.display.access.indexOf(item.access) !== -1 : false; const isAlias = Boolean(item.alias); const displayAlias = Boolean(ctx.display?.alias); return displayItemAccess && !(isAlias && !displayAlias); }); } export * from "./navigation"; export * from "./versions"; export * from "./config";