import { Ctx } from '../ctx/base'; import { isArray, isNullish, isNumber, isPlacement, isRecord, isString, } from '../guardUtils.js'; import { Icon, isIcon } from '../icon'; export type MainNavigationTabsHook = { /** * Use this function to declare new tabs you want to add in the top-bar of the * UI * * @tag pages */ mainNavigationTabs: (ctx: MainNavigationTabsCtx) => MainNavigationTab[]; }; export type MainNavigationTabsCtx = Ctx; /** * An object expressing a tab to be displayed in the top-bar of the UI * * @see {isMainNavigationTab} */ export type MainNavigationTab = { /** Label to be shown. Must be unique. */ label: string; /** * Icon to be shown alongside the label. Can be a FontAwesome icon name (ie. * `"address-book"`) or a custom SVG definition. To maintain visual * consistency with the rest of the interface, try to use FontAwesome icons * whenever possible. */ icon: Icon; /** ID of the page/inspector linked to the tab */ pointsTo: | { pageId: string; } | { inspectorId: string; /** The preferred width for the sidebar */ preferredWidth?: number; /** The inspector panel to render when first loaded */ initialInspectorPanel?: { /** ID of the inspector panel to render */ panelId: string; /** * An arbitrary configuration object that will be passed as the `parameters` * property of the second argument of the `renderInspectorPanel` function */ parameters?: Record; }; }; /** * Expresses where you want to place the tab in the top-bar. If not specified, * the tab will be placed after the standard tabs provided by DatoCMS itself. */ placement?: [ 'before' | 'after', 'content' | 'media' | 'schema' | 'configuration' | 'cdaPlayground', ]; /** * If different plugins specify the same `placement` for their tabs, they will * be displayed by ascending `rank`. If you want to specify an explicit value * for `rank`, make sure to offer a way for final users to customize it inside * the plugin's settings form, otherwise the hardcoded value you choose might * clash with the one of another plugin! */ rank?: number; }; export function isMainNavigationTab( value: unknown, ): value is MainNavigationTab { return ( isRecord(value) && isString(value.label) && isIcon(value.icon) && isRecord(value.pointsTo) && (isString(value.pointsTo.pageId) || (isString(value.pointsTo.inspectorId) && (isNullish(value.pointsTo.preferredWidth) || isNumber(value.pointsTo.preferredWidth)))) && (isNullish(value.placement) || isPlacement(value.placement)) && (isNullish(value.rank) || isNumber(value.rank)) ); } export function isReturnTypeOfMainNavigationTabsHook( value: unknown, ): value is MainNavigationTab[] { return isArray(value, isMainNavigationTab); }