1- import { computed , nextTick , onMounted , provide , reactive , Ref , ref , toValue , shallowRef } from 'vue' ;
1+ import { computed , nextTick , provide , reactive , Ref , ref , toValue , shallowRef } from 'vue' ;
22import { NoSchemaFormProps , useForm } from '../useForm' ;
33import { FormObject , IssueCollection , Path } from '../types' ;
44import { isObject , merge } from '../../../shared/src' ;
5- import { cloneDeep } from '../utils/common' ;
5+ import { cloneDeep , isSSR } from '../utils/common' ;
66import { FormFlowContextKey , SegmentMetadata , SegmentRegistrationMetadata , StepIdentifier } from './types' ;
77import { asConsumableData , ConsumableData } from '../useForm/useFormActions' ;
88import { createEventDispatcher } from '../utils/events' ;
@@ -25,6 +25,10 @@ export interface GoToPredicateContext {
2525 relativeDistance : number ;
2626}
2727
28+ export interface RenderedSegment {
29+ id : string ;
30+ }
31+
2832export function useFormFlow < TInput extends FormObject = FormObject > ( _props ?: FormFlowProps < TInput > ) {
2933 const currentSegmentId = ref < string > ( ) ;
3034 const formElement = shallowRef < HTMLElement > ( ) ;
@@ -33,9 +37,7 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
3337 const form = useForm ( _props ) ;
3438 const segments = ref < SegmentMetadata [ ] > ( [ ] ) ;
3539
36- function getCurrentSegment ( ) {
37- return segments . value . find ( segment => segment . id === currentSegmentId . value ) ;
38- }
40+ const rawCurrentSegment = computed ( ( ) => segments . value . find ( segment => segment . id === currentSegmentId . value ) ) ;
3941
4042 const [ dispatchActiveSegmentChange , onActiveSegmentChange ] = createEventDispatcher < {
4143 data : ConsumableData < TInput > ;
@@ -44,7 +46,7 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
4446 } > ( 'activeSegmentChange' ) ;
4547
4648 function beforeSegmentChange ( nextSegment : SegmentMetadata , applyChange : ( ) => void ) {
47- const currentSegment = getCurrentSegment ( ) ;
49+ const currentSegment = rawCurrentSegment . value ;
4850 if ( currentSegment ) {
4951 saveValues ( ) ;
5052 dispatchActiveSegmentChange ( {
@@ -59,7 +61,7 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
5961 }
6062
6163 function saveValues ( ) {
62- const currentSegment = getCurrentSegment ( ) ;
64+ const currentSegment = rawCurrentSegment . value ;
6365 if ( ! currentSegment ) {
6466 return ;
6567 }
@@ -74,20 +76,27 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
7476 }
7577
7678 provide ( FormFlowContextKey , {
77- isSegmentActive : ( segmentId : string ) => getCurrentSegment ( ) ?. id === segmentId ,
78- registerSegment : ( metadata : SegmentRegistrationMetadata ) =>
79+ isSegmentActive : ( segmentId : string ) => rawCurrentSegment . value ?. id === segmentId ,
80+ registerSegment : ( metadata : SegmentRegistrationMetadata ) => {
7981 segments . value . push ( {
8082 id : metadata . id ,
8183 name : ( ) => toValue ( metadata . name ) ,
8284 // The first segment is always visited.
8385 visited : segments . value . length === 0 ,
8486 submitted : false ,
8587 getValue : ( ) => segmentValuesMap . value . get ( metadata . id ) ?. values ,
86- } ) ,
88+ } ) ;
89+
90+ // Activate the first segment if there is only one by default
91+ // Fixes SSR #231
92+ if ( segments . value . length === 1 ) {
93+ currentSegmentId . value = metadata . id ;
94+ }
95+ } ,
8796 } ) ;
8897
8998 const currentSegment = computed ( ( ) => {
90- const curr = getCurrentSegment ( ) ;
99+ const curr = rawCurrentSegment . value ;
91100 if ( ! curr ) {
92101 return null ;
93102 }
@@ -101,7 +110,7 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
101110 return - 1 ;
102111 }
103112
104- return getDomSegments ( ) . findIndex ( segment => segment . dataset . formSegmentId === current . id ) ;
113+ return getRenderedSegments ( ) . findIndex ( segment => segment . id === current . id ) ;
105114 } ) ;
106115
107116 const isLastSegment = computed ( ( ) => currentSegmentIndex . value === segments . value . length - 1 ) ;
@@ -125,7 +134,7 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
125134
126135 async function restoreSegmentValues ( ) {
127136 await nextTick ( ) ;
128- const currentSegment = getCurrentSegment ( ) ;
137+ const currentSegment = rawCurrentSegment . value ;
129138 // restore field values
130139 if ( currentSegment && hasState ( currentSegment . id ) ) {
131140 const state = segmentValuesMap . value . get ( currentSegment . id ) as StepState < TInput > ;
@@ -136,14 +145,20 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
136145 }
137146 }
138147
139- function getDomSegments ( ) {
140- return Array . from ( formElement . value ?. querySelectorAll ( `[data-form-segment-id]` ) || [ ] ) as HTMLElement [ ] ;
148+ function getRenderedSegments ( ) : RenderedSegment [ ] {
149+ if ( isSSR ) {
150+ return segments . value . map ( segment => ( { id : segment . id } ) ) ;
151+ }
152+
153+ return Array . from ( formElement . value ?. querySelectorAll ( `[data-form-segment-id]` ) || [ ] ) . map ( segment => ( {
154+ id : ( segment as HTMLElement ) . dataset . formSegmentId ?? '' ,
155+ } ) ) ;
141156 }
142157
143158 function getSegmentAt ( idx : number ) : { idx : number ; segment : SegmentMetadata } | undefined {
144- const domSegments = getDomSegments ( ) ;
159+ const domSegments = getRenderedSegments ( ) ;
145160
146- const i = segments . value . findIndex ( segment => segment . id === domSegments [ idx ] . dataset . formSegmentId ) ;
161+ const i = segments . value . findIndex ( segment => segment . id === domSegments [ idx ] . id ) ;
147162 if ( i === - 1 ) {
148163 return undefined ;
149164 }
@@ -225,10 +240,6 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
225240 }
226241 }
227242
228- onMounted ( ( ) => {
229- moveRelative ( 0 ) ;
230- } ) ;
231-
232243 return {
233244 form,
234245
@@ -275,7 +286,7 @@ export function useFormFlow<TInput extends FormObject = FormObject>(_props?: For
275286 /**
276287 * Returns the DOM segments.
277288 */
278- getDomSegments ,
289+ getRenderedSegments ,
279290
280291 /**
281292 * The segments.
0 commit comments