diff --git a/packages/sanity/src/core/config/studio/types.ts b/packages/sanity/src/core/config/studio/types.ts index b431c956b9da..ab5681833d90 100644 --- a/packages/sanity/src/core/config/studio/types.ts +++ b/packages/sanity/src/core/config/studio/types.ts @@ -1,4 +1,4 @@ -import {type ComponentType, type ReactElement, type ReactNode} from 'react' +import {type ComponentType, type ReactElement} from 'react' import {type Tool} from '../types' @@ -18,15 +18,30 @@ export interface LogoProps { renderDefault: (props: LogoProps) => ReactElement } +/** + * @internal + * @beta + * An internal API for defining actions in the navbar. + */ +export interface NavbarAction { + icon?: React.ComponentType + location: 'topbar' | 'sidebar' + name: string + onAction: () => void + selected: boolean + title: string +} + /** * @hidden * @beta */ export interface NavbarProps { renderDefault: (props: NavbarProps) => ReactElement + /** * @internal * @beta */ - __internal_rightSectionNode?: ReactNode + __internal_actions?: NavbarAction[] } /** diff --git a/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx b/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx index 1de2e4eb133b..93081fa14d42 100644 --- a/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx +++ b/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx @@ -35,6 +35,8 @@ import {SearchProvider} from './search/contexts/search/SearchProvider' import {UserMenu} from './userMenu' import {WorkspaceMenuButton} from './workspace' +const EMPTY_ARRAY: [] = [] + const RootLayer = styled(Layer)` min-height: auto; position: relative; @@ -60,8 +62,11 @@ const NavGrid = styled(Grid)` * @hidden * @beta */ export function StudioNavbar(props: Omit) { - // eslint-disable-next-line camelcase - const {__internal_rightSectionNode = null} = props + const { + // eslint-disable-next-line camelcase + __internal_actions: actions = EMPTY_ARRAY, + } = props + const {name, tools} = useWorkspace() const routerState = useRouterState() const mediaIndex = useMediaIndex() @@ -153,6 +158,25 @@ export function StudioNavbar(props: Omit) { setDrawerOpen(true) }, []) + const actionNodes = useMemo(() => { + if (!shouldRender.tools) return null + + return actions + ?.filter((v) => v.location === 'topbar') + ?.map((action) => { + return ( +