@@ -5,6 +5,7 @@ import { useCheckForContentUpdate } from '../AutoRefreshContent';
55import { useVisitorSession } from '../Insights' ;
66import { useCurrentPagePath } from '../hooks' ;
77import { DateRelative } from '../primitives' ;
8+ import { HideToolbarButton } from './HideToolbarButton' ;
89import { IframeWrapper } from './IframeWrapper' ;
910import { RefreshContentButton } from './RefreshContentButton' ;
1011import {
@@ -17,48 +18,108 @@ import {
1718 ToolbarSubtitle ,
1819 ToolbarTitle ,
1920} from './Toolbar' ;
20- import type { AdminToolbarClientProps } from './types' ;
21+ import {
22+ type ToolbarControlsContextValue ,
23+ ToolbarControlsProvider ,
24+ } from './ToolbarControlsContext' ;
25+ import type { AdminToolbarClientProps , AdminToolbarContext } from './types' ;
26+ import { useToolbarVisibility } from './utils' ;
2127
2228export function AdminToolbarClient ( props : AdminToolbarClientProps ) {
23- const { context } = props ;
29+ const { context, onPersistentClose, onSessionClose, onToggleMinify } = props ;
30+ const {
31+ minified,
32+ setMinified,
33+ shouldAutoExpand,
34+ hidden,
35+ minimize,
36+ closeSession,
37+ closePersistent,
38+ } = useToolbarVisibility ( {
39+ onPersistentClose,
40+ onSessionClose,
41+ onToggleMinify,
42+ } ) ;
43+
2444 const visitorSession = useVisitorSession ( ) ;
2545
46+ const toolbarControls : ToolbarControlsContextValue = {
47+ minimize,
48+ closeSession,
49+ closePersistent,
50+ shouldAutoExpand,
51+ } ;
52+
53+ if ( hidden ) {
54+ return null ;
55+ }
56+
2657 // If there is a change request, show the change request toolbar
2758 if ( context . changeRequest ) {
2859 return (
29- < IframeWrapper >
30- < MotionConfig reducedMotion = "user" >
31- < ChangeRequestToolbar context = { context } />
32- </ MotionConfig >
33- </ IframeWrapper >
60+ < ToolbarControlsWrapper value = { toolbarControls } >
61+ < ChangeRequestToolbar
62+ context = { context }
63+ minified = { minified }
64+ onMinifiedChange = { setMinified }
65+ />
66+ </ ToolbarControlsWrapper >
3467 ) ;
3568 }
3669
3770 // If the revision is not the current revision, the user is looking at a previous version of the site, so show the revision toolbar
3871 if ( context . revisionId !== context . space . revision ) {
3972 return (
40- < IframeWrapper >
41- < MotionConfig reducedMotion = "user" >
42- < RevisionToolbar context = { context } />
43- </ MotionConfig >
44- </ IframeWrapper >
73+ < ToolbarControlsWrapper value = { toolbarControls } >
74+ < RevisionToolbar
75+ context = { context }
76+ minified = { minified }
77+ onMinifiedChange = { setMinified }
78+ />
79+ </ ToolbarControlsWrapper >
4580 ) ;
4681 }
4782
4883 // If the user is authenticated and part of the organization owning this site, show the authenticated user toolbar
4984 if ( visitorSession ?. organizationId === context . organizationId ) {
5085 return (
51- < IframeWrapper >
52- < MotionConfig reducedMotion = "user" >
53- < AuthenticatedUserToolbar context = { context } />
54- </ MotionConfig >
55- </ IframeWrapper >
86+ < ToolbarControlsWrapper value = { toolbarControls } >
87+ < AuthenticatedUserToolbar
88+ context = { context }
89+ minified = { minified }
90+ onMinifiedChange = { setMinified }
91+ />
92+ </ ToolbarControlsWrapper >
5693 ) ;
5794 }
95+
96+ return null ;
5897}
5998
60- function ChangeRequestToolbar ( props : AdminToolbarClientProps ) {
61- const { context } = props ;
99+ /**
100+ * Reusable wrapper that provides tooling and containers that are used by all types of toolbar views.
101+ */
102+ export function ToolbarControlsWrapper (
103+ props : React . PropsWithChildren < { value : ToolbarControlsContextValue | null } >
104+ ) {
105+ const { children, value } = props ;
106+ return (
107+ < ToolbarControlsProvider value = { value } >
108+ < IframeWrapper >
109+ < MotionConfig reducedMotion = "user" > { children } </ MotionConfig >
110+ </ IframeWrapper >
111+ </ ToolbarControlsProvider >
112+ ) ;
113+ }
114+
115+ interface ToolbarViewProps {
116+ context : AdminToolbarContext ;
117+ minified : boolean ;
118+ onMinifiedChange : ( value : boolean ) => void ;
119+ }
120+
121+ function ChangeRequestToolbar ( props : ToolbarViewProps ) {
122+ const { context, minified, onMinifiedChange } = props ;
62123 const { changeRequest, site } = context ;
63124 if ( ! changeRequest ) {
64125 throw new Error ( 'Change request is not set' ) ;
@@ -71,11 +132,11 @@ function ChangeRequestToolbar(props: AdminToolbarClientProps) {
71132 } ) ;
72133
73134 return (
74- < Toolbar label = "Site preview" >
135+ < Toolbar minified = { minified } onMinifiedChange = { onMinifiedChange } label = "Site preview" >
75136 < ToolbarBody >
76137 < ToolbarTitle
77- prefix = " Change request"
78- suffix = { `# ${ changeRequest . number } ${ changeRequest . subject || 'Untitled' } ` }
138+ prefix = { ` Change # ${ changeRequest . number } :` }
139+ suffix = { `${ changeRequest . subject || 'Untitled' } ` }
79140 />
80141 < ToolbarSubtitle
81142 subtitle = {
@@ -88,9 +149,13 @@ function ChangeRequestToolbar(props: AdminToolbarClientProps) {
88149
89150 < ToolbarSeparator />
90151
91- < ToolbarButtonGroup >
152+ < ToolbarActions >
92153 { /* Refresh to retrieve latest changes */ }
93154 { updated ? < RefreshContentButton refreshForUpdates = { refreshForUpdates } /> : null }
155+
156+ { /* Edit in GitBook */ }
157+ < EditPageButton href = { changeRequest . urls . app } siteId = { site . id } />
158+
94159 { /* Comment in app */ }
95160 < ToolbarButton
96161 title = "Comment in a GitBook"
@@ -125,16 +190,13 @@ function ChangeRequestToolbar(props: AdminToolbarClientProps) {
125190 } ) }
126191 icon = "code-pull-request"
127192 />
128-
129- { /* Edit in GitBook */ }
130- < EditPageButton href = { changeRequest . urls . app } siteId = { site . id } />
131- </ ToolbarButtonGroup >
193+ </ ToolbarActions >
132194 </ Toolbar >
133195 ) ;
134196}
135197
136- function RevisionToolbar ( props : AdminToolbarClientProps ) {
137- const { context } = props ;
198+ function RevisionToolbar ( props : ToolbarViewProps ) {
199+ const { context, minified , onMinifiedChange } = props ;
138200 const { revision, site } = context ;
139201 if ( ! revision ) {
140202 throw new Error ( 'Revision is not set' ) ;
@@ -145,7 +207,7 @@ function RevisionToolbar(props: AdminToolbarClientProps) {
145207 const gitProvider = isGitHub ? 'GitHub' : 'GitLab' ;
146208
147209 return (
148- < Toolbar label = "Site preview" >
210+ < Toolbar minified = { minified } onMinifiedChange = { onMinifiedChange } label = "Site preview" >
149211 < ToolbarBody >
150212 < ToolbarTitle prefix = "Site version" suffix = { context . site . title } />
151213 < ToolbarSubtitle
@@ -157,7 +219,7 @@ function RevisionToolbar(props: AdminToolbarClientProps) {
157219 />
158220 </ ToolbarBody >
159221 < ToolbarSeparator />
160- < ToolbarButtonGroup >
222+ < ToolbarActions >
161223 { /* Open commit in Git client */ }
162224 < ToolbarButton
163225 title = {
@@ -205,22 +267,26 @@ function RevisionToolbar(props: AdminToolbarClientProps) {
205267 } ) }
206268 icon = "code-commit"
207269 />
208- </ ToolbarButtonGroup >
270+ </ ToolbarActions >
209271 </ Toolbar >
210272 ) ;
211273}
212274
213- function AuthenticatedUserToolbar ( props : AdminToolbarClientProps ) {
214- const { context } = props ;
275+ function AuthenticatedUserToolbar ( props : ToolbarViewProps ) {
276+ const { context, minified , onMinifiedChange } = props ;
215277 const { revision, space, site } = context ;
216278 const { refreshForUpdates, updated } = useCheckForContentUpdate ( {
217279 revisionId : space . revision ,
218280 } ) ;
219281
220282 return (
221- < Toolbar label = "Only visible to your GitBook organization" >
283+ < Toolbar
284+ minified = { minified }
285+ onMinifiedChange = { onMinifiedChange }
286+ label = "Only visible to your GitBook organization"
287+ >
222288 < ToolbarBody >
223- < ToolbarTitle prefix = "Site" suffix = { context . site . title } />
289+ < ToolbarTitle suffix = { context . site . title } />
224290 < ToolbarSubtitle
225291 subtitle = {
226292 < >
@@ -230,18 +296,25 @@ function AuthenticatedUserToolbar(props: AdminToolbarClientProps) {
230296 />
231297 </ ToolbarBody >
232298 < ToolbarSeparator />
233- < ToolbarButtonGroup >
299+ < ToolbarActions >
234300 { /* Refresh to retrieve latest changes */ }
235301 { updated ? < RefreshContentButton refreshForUpdates = { refreshForUpdates } /> : null }
302+
303+ { /* Edit in GitBook */ }
304+ < EditPageButton href = { space . urls . app } siteId = { site . id } />
305+
306+ { /* Open site in GitBook */ }
236307 < ToolbarButton
237308 title = "Open site in GitBook"
238309 href = { getToolbarHref ( {
239310 href : site . urls . app ,
240311 siteId : site . id ,
241312 buttonId : 'site' ,
242313 } ) }
243- icon = "gear "
314+ icon = "gears "
244315 />
316+
317+ { /* Customize in GitBook */ }
245318 < ToolbarButton
246319 title = "Customize in GitBook"
247320 href = { getToolbarHref ( {
@@ -251,6 +324,8 @@ function AuthenticatedUserToolbar(props: AdminToolbarClientProps) {
251324 } ) }
252325 icon = "palette"
253326 />
327+
328+ { /* Open insights in GitBook */ }
254329 < ToolbarButton
255330 title = "Open insights in GitBook"
256331 href = { getToolbarHref ( {
@@ -260,12 +335,22 @@ function AuthenticatedUserToolbar(props: AdminToolbarClientProps) {
260335 } ) }
261336 icon = "chart-simple"
262337 />
263- < EditPageButton href = { space . urls . app } siteId = { site . id } />
264- </ ToolbarButtonGroup >
338+ </ ToolbarActions >
265339 </ Toolbar >
266340 ) ;
267341}
268342
343+ function ToolbarActions ( props : { children : React . ReactNode } ) {
344+ const { children } = props ;
345+
346+ return (
347+ < ToolbarButtonGroup >
348+ { children }
349+ < HideToolbarButton />
350+ </ ToolbarButtonGroup >
351+ ) ;
352+ }
353+
269354function EditPageButton ( props : {
270355 href : string ;
271356 siteId : string ;
0 commit comments