11import React from 'react' ;
22import classNames from 'classnames' ;
3-
43import { MyForms } from '../routes.js' ;
54import { useFormManagerStore } from '../store.js' ;
65import styles from './formManagerStyles.module.css' ;
@@ -12,35 +11,76 @@ export enum NavPage {
1211 preview = 4 ,
1312}
1413
15- const stepClass = ( page : NavPage , curPage : NavPage ) => {
16- if ( page < curPage ) {
17- return 'usa-step-indicator__segment--complete' ;
18- } else if ( page === curPage ) {
19- return 'usa-step-indicator__segment--current' ;
20- } else {
21- return '' ;
22- }
23- } ;
14+ const stepClass = ( page : NavPage , curPage : NavPage ) =>
15+ page < curPage
16+ ? 'usa-step-indicator__segment--complete'
17+ : page === curPage
18+ ? 'usa-step-indicator__segment--current'
19+ : '' ;
2420
25- const srHint = ( page : NavPage , curPage : NavPage ) => {
26- if ( page < curPage ) {
27- return < span className = "usa-sr-only" > completed</ span > ;
28- } else if ( page === curPage ) {
29- return ;
30- } else {
31- return < span className = "usa-sr-only" > not completed</ span > ;
32- }
33- } ;
21+ const srHint = ( page : NavPage , curPage : NavPage ) =>
22+ page < curPage ? (
23+ < span className = "usa-sr-only" > completed</ span >
24+ ) : page > curPage ? (
25+ < span className = "usa-sr-only" > not completed</ span >
26+ ) : null ;
3427
3528export const TopNavigation = ( {
3629 curPage,
37- preview,
30+ previewPath,
31+ currentPath,
32+ back,
3833} : {
3934 curPage : NavPage ;
40- preview ?: string ;
35+ previewPath ?: string ;
36+ currentPath ?: string ;
37+ back ?: string ;
4138} ) => {
39+ const isPreview = previewPath === currentPath ;
4240 const uswdsRoot = useFormManagerStore ( state => state . context . uswdsRoot ) ;
4341 const lastSaved = useFormManagerStore ( state => state . saveStatus . lastSaved ) ;
42+ const capitalize = ( value : string ) =>
43+ value . charAt ( 0 ) . toUpperCase ( ) + value . slice ( 1 ) ;
44+
45+ const renderStepIndicator = ( isPreview : boolean ) => (
46+ < ol className = "usa-step-indicator__segments desktop:grid-col-6 tablet:grid-col-5" >
47+ { ! isPreview ? (
48+ [ NavPage . edit , NavPage . settings , NavPage . publish ] . map ( page => (
49+ < li
50+ key = { page }
51+ className = { classNames (
52+ 'usa-step-indicator__segment font-body-xs' ,
53+ stepClass ( page , curPage )
54+ ) }
55+ aria-current = { page === curPage ? 'true' : undefined }
56+ >
57+ < span className = "usa-step-indicator__segment-label" >
58+ { capitalize ( NavPage [ page ] ) } { srHint ( page , curPage ) }
59+ </ span >
60+ </ li >
61+ ) )
62+ ) : (
63+ < li className = "placeholder" aria-hidden = "true" > </ li > // Placeholder for consistent layout
64+ ) }
65+ </ ol >
66+ ) ;
67+
68+ const renderSavedStatus = ( ) => (
69+ < span
70+ className = { `text-base font-ui-3xs padding-left-1 display-inline-block text-middle ${ styles . savedStatus } ` }
71+ >
72+ { lastSaved
73+ ? `Saved ${ lastSaved . toLocaleDateString ( 'en-us' , {
74+ month : 'short' ,
75+ day : 'numeric' ,
76+ hour : 'numeric' ,
77+ minute : 'numeric' ,
78+ second : 'numeric' ,
79+ } ) } `
80+ : 'Blueprint loaded' }
81+ </ span >
82+ ) ;
83+
4484 return (
4585 < div className = "position-sticky top-0 z-100 bg-white border-bottom border-bottom-width-1px border-base-lighter padding-1" >
4686 < div className = "grid-container grid-row margin-bottom-105 display-block tablet:display-none" >
@@ -50,76 +90,35 @@ export const TopNavigation = ({
5090 </ div >
5191 < div className = "grid-col-6 text-base text-right font-ui-3xs padding-left-4" >
5292 < span className = "padding-right-2" > Saved</ span >
53- { preview && < PreviewIconLink url = { preview } uswdsRoot = { uswdsRoot } /> }
93+ { previewPath && (
94+ < PreviewIconLink url = { previewPath } uswdsRoot = { uswdsRoot } />
95+ ) }
5496 </ div >
5597 </ div >
5698 < MobileStepIndicator curPage = { curPage } />
5799 </ div >
58100 < div className = "display-none tablet:display-block margin-top-1 margin-bottom-1" >
59101 < div className = "grid-container" >
60102 < div
61- className = "grid-row margin-bottom-0 classes usa-step-indicator "
103+ className = "grid-row margin-bottom-0 classes usa-step-indicator"
62104 aria-label = "progress"
63105 >
64106 < div className = "margin-top-1 grid-col-2" >
65- < MyFormsLink uswdsRoot = { uswdsRoot } />
107+ { isPreview ? (
108+ < EditFormsLink uswdsRoot = { uswdsRoot } path = { back } />
109+ ) : (
110+ < MyFormsLink uswdsRoot = { uswdsRoot } path = { MyForms . getUrl ( ) } />
111+ ) }
66112 </ div >
67- < ol className = "usa-step-indicator__segments desktop:grid-col-6 tablet:grid-col-5" >
68- < li
69- className = { classNames (
70- 'usa-step-indicator__segment font-body-xs' ,
71- stepClass ( NavPage . edit , curPage )
72- ) }
73- >
74- < span className = "usa-step-indicator__segment-label" >
75- Edit { srHint ( NavPage . edit , curPage ) }
76- </ span >
77- </ li >
78- < li
79- className = { classNames (
80- 'usa-step-indicator__segment font-body-xs' ,
81- stepClass ( NavPage . settings , curPage )
82- ) }
83- aria-current = "true"
84- >
85- < span className = "usa-step-indicator__segment-label" >
86- Settings { srHint ( NavPage . settings , curPage ) }
87- </ span >
88- </ li >
89- < li
90- className = { classNames (
91- 'usa-step-indicator__segment font-body-xs' ,
92- stepClass ( NavPage . publish , curPage )
93- ) }
94- >
95- < span className = "usa-step-indicator__segment-label" >
96- Publish { srHint ( NavPage . publish , curPage ) }
97- </ span >
98- </ li >
99- </ ol >
113+ { renderStepIndicator ( isPreview ) }
100114 < div className = "desktop:grid-col-4 tablet:grid-col-5 text-right" >
101- < span
102- className = { `text-base font-ui-3xs padding-left-1 display-inline-block text-middle ${ styles . savedStatus } ` }
115+ { renderSavedStatus ( ) }
116+ < a
117+ href = { isPreview ? back : previewPath }
118+ className = "usa-button usa-button--outline margin-left-1 display-inline-block text-middle"
103119 >
104- { lastSaved
105- ? 'Saved ' +
106- lastSaved . toLocaleDateString ( 'en-us' , {
107- month : 'short' ,
108- day : 'numeric' ,
109- hour : 'numeric' ,
110- minute : 'numeric' ,
111- second : 'numeric' ,
112- } )
113- : 'Blueprint loaded' }
114- </ span >
115- { preview && (
116- < a
117- href = { preview }
118- className = "usa-button usa-button--outline margin-left-1 display-inline-block text-middle"
119- >
120- Preview
121- </ a >
122- ) }
120+ { isPreview ? 'Exit preview' : 'Preview' }
121+ </ a >
123122 </ div >
124123 </ div >
125124 </ div >
@@ -128,8 +127,14 @@ export const TopNavigation = ({
128127 ) ;
129128} ;
130129
131- const MyFormsLink = ( { uswdsRoot } : { uswdsRoot : `${string } /` } ) => (
132- < a href = { MyForms . getUrl ( ) } className = "usa-link margin-right-1 display-block" >
130+ const MyFormsLink = ( {
131+ uswdsRoot,
132+ path,
133+ } : {
134+ uswdsRoot : `${string } /`;
135+ path ?: string ;
136+ } ) => (
137+ < a href = { path } className = "usa-link margin-right-1 display-block" >
133138 < svg
134139 className = "usa-icon usa-icon--size-3 text-middle margin-right-1"
135140 aria-hidden = "true"
@@ -142,25 +147,43 @@ const MyFormsLink = ({ uswdsRoot }: { uswdsRoot: `${string}/` }) => (
142147 </ a >
143148) ;
144149
150+ const EditFormsLink = ( {
151+ uswdsRoot,
152+ path,
153+ } : {
154+ uswdsRoot : `${string } /`;
155+ path ?: string ;
156+ } ) => (
157+ < a href = { path } className = "usa-link margin-right-1 display-block" >
158+ < svg
159+ className = "usa-icon usa-icon--size-3 text-middle margin-right-1"
160+ aria-hidden = "true"
161+ focusable = "false"
162+ role = "img"
163+ >
164+ < use xlinkHref = { `${ uswdsRoot } img/sprite.svg#arrow_back` } > </ use >
165+ </ svg >
166+ Edit form
167+ </ a >
168+ ) ;
169+
145170const PreviewIconLink = ( {
146171 url,
147172 uswdsRoot,
148173} : {
149174 url : string ;
150175 uswdsRoot : `${string } /`;
151- } ) => {
152- return (
153- < a
154- href = { url }
155- className = "usa-link tablet:margin-right-4"
156- aria-label = "Preview this blueprint"
157- >
158- < svg className = "usa-icon" aria-hidden = "true" focusable = "false" role = "img" >
159- < use xlinkHref = { `${ uswdsRoot } img/sprite.svg#visibility` } > </ use >
160- </ svg >
161- </ a >
162- ) ;
163- } ;
176+ } ) => (
177+ < a
178+ href = { url }
179+ className = "usa-link tablet:margin-right-4"
180+ aria-label = "Preview this blueprint"
181+ >
182+ < svg className = "usa-icon" aria-hidden = "true" focusable = "false" role = "img" >
183+ < use xlinkHref = { `${ uswdsRoot } img/sprite.svg#visibility` } > </ use >
184+ </ svg >
185+ </ a >
186+ ) ;
164187
165188const MobileStepIndicator = ( { curPage } : { curPage : NavPage } ) => (
166189 < div className = "grid-row grid-gap flex-align-center" >
@@ -170,7 +193,7 @@ const MobileStepIndicator = ({ curPage }: { curPage: NavPage }) => (
170193 < span className = "usa-step-indicator__current-step" > 1</ span >
171194 < span className = "usa-step-indicator__total-steps margin-left-05" >
172195 of 3
173- </ span > { ' ' }
196+ </ span >
174197 </ span >
175198 </ div >
176199 < div className = "grid-col grid-col-8" >
@@ -187,3 +210,5 @@ const MobileStepIndicator = ({ curPage }: { curPage: NavPage }) => (
187210 </ div >
188211 </ div >
189212) ;
213+
214+ export default TopNavigation ;
0 commit comments