From 5369a5e3dae5216dff58fd3a1da569866a673ae4 Mon Sep 17 00:00:00 2001 From: Pedro Bonamin Date: Fri, 2 Feb 2024 11:19:46 +0100 Subject: [PATCH 1/2] feat(core): add StudioActiveToolLayout api --- .../sanity/src/core/config/studio/types.ts | 9 +++++++++ .../sanity/src/core/studio/StudioLayout.tsx | 19 ++++++++----------- .../navbar/StudioActiveToolLayout.tsx | 12 ++++++++++++ .../studio-components-hooks/componentHooks.ts | 17 +++++++++++++++++ .../studio/studio-components-hooks/picks.ts | 9 +++++++++ 5 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 packages/sanity/src/core/studio/components/navbar/StudioActiveToolLayout.tsx diff --git a/packages/sanity/src/core/config/studio/types.ts b/packages/sanity/src/core/config/studio/types.ts index f581e9481ae..dc64320c209 100644 --- a/packages/sanity/src/core/config/studio/types.ts +++ b/packages/sanity/src/core/config/studio/types.ts @@ -25,6 +25,14 @@ export interface NavbarProps { renderDefault: (props: NavbarProps) => ReactElement } +/** + * @hidden + * @beta */ +export interface ActiveToolLayoutProps { + renderDefault: (props: ActiveToolLayoutProps) => React.ReactElement + activeTool: Tool +} + /** * @hidden * @beta */ @@ -52,6 +60,7 @@ export interface StudioComponents { * @hidden * @beta */ export interface StudioComponentsPluginOptions { + activeToolLayout?: ComponentType layout?: ComponentType /** * @deprecated Add custom icons on a per-workspace basis by customizing workspace `icon` instead. diff --git a/packages/sanity/src/core/studio/StudioLayout.tsx b/packages/sanity/src/core/studio/StudioLayout.tsx index a76e1c63cce..5fe70a2ada2 100644 --- a/packages/sanity/src/core/studio/StudioLayout.tsx +++ b/packages/sanity/src/core/studio/StudioLayout.tsx @@ -1,15 +1,7 @@ /* eslint-disable i18next/no-literal-string, @sanity/i18n/no-attribute-template-literals */ import {Card, Flex} from '@sanity/ui' import {startCase} from 'lodash' -import { - createContext, - createElement, - Suspense, - useCallback, - useEffect, - useMemo, - useState, -} from 'react' +import {createContext, Suspense, useCallback, useEffect, useMemo, useState} from 'react' import {RouteScope, useRouter, useRouterState} from 'sanity/router' import styled from 'styled-components' @@ -17,7 +9,11 @@ import {LoadingBlock} from '../components/loadingBlock' import {NoToolsScreen} from './screens/NoToolsScreen' import {RedirectingScreen} from './screens/RedirectingScreen' import {ToolNotFoundScreen} from './screens/ToolNotFoundScreen' -import {useLayoutComponent, useNavbarComponent} from './studio-components-hooks' +import { + useActiveToolLayoutComponent, + useLayoutComponent, + useNavbarComponent, +} from './studio-components-hooks' import {StudioErrorBoundary} from './StudioErrorBoundary' import {useWorkspace} from './workspace' @@ -146,6 +142,7 @@ export function StudioLayoutComponent() { ) const Navbar = useNavbarComponent() + const ActiveToolLayout = useActiveToolLayoutComponent() /** * Handle legacy URL redirects from `/desk` to `/structure` @@ -193,7 +190,7 @@ export function StudioLayoutComponent() { } > }> - {createElement(activeTool.component, {tool: activeTool})} + )} diff --git a/packages/sanity/src/core/studio/components/navbar/StudioActiveToolLayout.tsx b/packages/sanity/src/core/studio/components/navbar/StudioActiveToolLayout.tsx new file mode 100644 index 00000000000..ec2e6421e08 --- /dev/null +++ b/packages/sanity/src/core/studio/components/navbar/StudioActiveToolLayout.tsx @@ -0,0 +1,12 @@ +import {createElement} from 'react' + +import {type Tool} from '../../../config' + +interface StudioActiveToolLayoutProps { + activeTool: Tool +} + +export function StudioActiveToolLayout(props: StudioActiveToolLayoutProps) { + const {activeTool} = props + return createElement(activeTool.component, {tool: activeTool}) +} diff --git a/packages/sanity/src/core/studio/studio-components-hooks/componentHooks.ts b/packages/sanity/src/core/studio/studio-components-hooks/componentHooks.ts index 2c451199a37..ed3febeae6e 100644 --- a/packages/sanity/src/core/studio/studio-components-hooks/componentHooks.ts +++ b/packages/sanity/src/core/studio/studio-components-hooks/componentHooks.ts @@ -2,14 +2,17 @@ import {type ComponentType} from 'react' import {useMiddlewareComponents} from '../../config' import { + type ActiveToolLayoutProps, type LayoutProps, type LogoProps, type NavbarProps, type ToolMenuProps, } from '../../config/studio' import {StudioLogo, StudioNavbar, StudioToolMenu} from '../components' +import {StudioActiveToolLayout} from '../components/navbar/StudioActiveToolLayout' import {StudioLayoutComponent} from '../StudioLayout' import { + pickActiveToolLayoutComponent, pickLayoutComponent, pickLogoComponent, pickNavbarComponent, @@ -56,3 +59,17 @@ export function useLayoutComponent(): ComponentType +> { + return useMiddlewareComponents({ + defaultComponent: StudioActiveToolLayout as ComponentType< + Omit + >, + pick: pickActiveToolLayoutComponent, + }) +} diff --git a/packages/sanity/src/core/studio/studio-components-hooks/picks.ts b/packages/sanity/src/core/studio/studio-components-hooks/picks.ts index ac2257d884c..67995b96ff6 100644 --- a/packages/sanity/src/core/studio/studio-components-hooks/picks.ts +++ b/packages/sanity/src/core/studio/studio-components-hooks/picks.ts @@ -1,6 +1,7 @@ import {type ComponentType} from 'react' import { + type ActiveToolLayoutProps, type LayoutProps, type LogoProps, type NavbarProps, @@ -31,3 +32,11 @@ export function pickLogoComponent( ): ComponentType> { return plugin.studio?.components?.logo as ComponentType> } + +export function pickActiveToolLayoutComponent( + plugin: PluginOptions, +): ComponentType> { + return plugin.studio?.components?.activeToolLayout as ComponentType< + Omit + > +} From 7daf0c2a3e0695984b3ea91aad1a4297a20b630b Mon Sep 17 00:00:00 2001 From: Pedro Bonamin Date: Fri, 9 Feb 2024 09:55:25 +0100 Subject: [PATCH 2/2] feat(core): add studioNavbar __internal_rightSectionNode prop --- packages/sanity/src/core/config/studio/types.ts | 6 +++++- .../core/studio/components/navbar/StudioNavbar.tsx | 11 +++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/sanity/src/core/config/studio/types.ts b/packages/sanity/src/core/config/studio/types.ts index dc64320c209..b431c956b9d 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} from 'react' +import {type ComponentType, type ReactElement, type ReactNode} from 'react' import {type Tool} from '../types' @@ -23,6 +23,10 @@ export interface LogoProps { * @beta */ export interface NavbarProps { renderDefault: (props: NavbarProps) => ReactElement + /** + * @internal + * @beta */ + __internal_rightSectionNode?: ReactNode } /** diff --git a/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx b/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx index ff70b8d9649..1de2e4eb133 100644 --- a/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx +++ b/packages/sanity/src/core/studio/components/navbar/StudioNavbar.tsx @@ -15,6 +15,7 @@ import {type RouterState, useRouterState} from 'sanity/router' import styled from 'styled-components' import {Button, TooltipDelayGroupProvider} from '../../../../ui-components' +import {type NavbarProps} from '../../../config/studio/types' import {isDev} from '../../../environment' import {useTranslation} from '../../../i18n' import {useToolMenuComponent} from '../../studio-components-hooks' @@ -58,7 +59,9 @@ const NavGrid = styled(Grid)` /** * @hidden * @beta */ -export function StudioNavbar() { +export function StudioNavbar(props: Omit) { + // eslint-disable-next-line camelcase + const {__internal_rightSectionNode = null} = props const {name, tools} = useWorkspace() const routerState = useRouterState() const mediaIndex = useMediaIndex() @@ -233,7 +236,6 @@ export function StudioNavbar() { - {shouldRender.tools && } {shouldRender.configIssues && } {shouldRender.resources && } @@ -245,6 +247,11 @@ export function StudioNavbar() { ref={setSearchOpenButtonEl} /> )} + + { + // eslint-disable-next-line camelcase + __internal_rightSectionNode + } {shouldRender.tools && (