10
10
* governing permissions and limitations under the License.
11
11
*/
12
12
13
- import { BaseCollection } from './BaseCollection' ;
13
+ import { BaseCollection , CollectionNode } from './BaseCollection' ;
14
14
import { BaseNode , Document , ElementNode } from './Document' ;
15
15
import { CachedChildrenOptions , useCachedChildren } from './useCachedChildren' ;
16
16
import { createPortal } from 'react-dom' ;
17
17
import { FocusableContext } from '@react-aria/interactions' ;
18
- import { forwardRefType , Node } from '@react-types/shared' ;
18
+ import { forwardRefType , Key , Node } from '@react-types/shared' ;
19
19
import { Hidden } from './Hidden' ;
20
20
import React , { createContext , ForwardedRef , forwardRef , JSX , ReactElement , ReactNode , useCallback , useContext , useMemo , useRef , useState } from 'react' ;
21
21
import { useIsSSR } from '@react-aria/ssr' ;
@@ -127,24 +127,29 @@ function useCollectionDocument<T extends object, C extends BaseCollection<T>>(cr
127
127
128
128
const SSRContext = createContext < BaseNode < any > | null > ( null ) ;
129
129
130
- // TODO: make this any for now, but should be a node class
131
- function useSSRCollectionNode < T extends Element > ( Type : any , props : object , ref : ForwardedRef < T > , rendered ?: any , children ?: ReactNode , render ?: ( node : Node < T > ) => ReactElement ) {
132
- // function useSSRCollectionNode<T extends Element>(Type: string, props: object, ref: ForwardedRef<T>, rendered?: any, children?: ReactNode, render?: (node: Node<T>) => ReactElement) {
130
+ export type CollectionNodeClass < T > = {
131
+ new ( key : Key ) : CollectionNode < T > ,
132
+ readonly type : string
133
+ } ;
134
+
135
+ // TODO: discuss the former Type arg, renamed to CollectionNodeClass
136
+ function useSSRCollectionNode < T extends Element > ( CollectionNodeClass : CollectionNodeClass < T > , props : object , ref : ForwardedRef < T > , rendered ?: any , children ?: ReactNode , render ?: ( node : Node < any > ) => ReactElement ) {
133
137
// During SSR, portals are not supported, so the collection children will be wrapped in an SSRContext.
134
138
// Since SSR occurs only once, we assume that the elements are rendered in order and never re-render.
135
139
// Therefore we can create elements in our collection document during render so that they are in the
136
140
// collection by the time we need to use the collection to render to the real DOM.
137
141
// After hydration, we switch to client rendering using the portal.
138
142
let itemRef = useCallback ( ( element : ElementNode < any > | null ) => {
139
- // TODO: now we get the proper node class aka TreeNode
140
- element ?. setProps ( props , ref , rendered , render , Type ) ;
141
- } , [ props , ref , rendered , render , Type ] ) ;
143
+ // TODO: check setProps api
144
+ element ?. setProps ( props , ref , rendered , render , CollectionNodeClass ) ;
145
+ } , [ props , ref , rendered , render , CollectionNodeClass ] ) ;
142
146
let parentNode = useContext ( SSRContext ) ;
143
147
if ( parentNode ) {
144
148
// Guard against double rendering in strict mode.
145
149
let element = parentNode . ownerDocument . nodesByProps . get ( props ) ;
146
150
if ( ! element ) {
147
- element = parentNode . ownerDocument . createElement ( Type ) ;
151
+ // TODO: check this, maybe should just pass the CollectionNodeClass as a whole?
152
+ element = parentNode . ownerDocument . createElement ( CollectionNodeClass . type ) ;
148
153
element . setProps ( props , ref , rendered , render ) ;
149
154
parentNode . appendChild ( element ) ;
150
155
parentNode . ownerDocument . updateCollection ( ) ;
@@ -156,15 +161,16 @@ function useSSRCollectionNode<T extends Element>(Type: any, props: object, ref:
156
161
: null ;
157
162
}
158
163
164
+ // console.log('type', CollectionNodeClass, CollectionNodeClass.type)
159
165
// @ts -ignore
160
- // TODO: make div for now, may not actually matter
161
- return < div ref = { itemRef } > { children } </ div > ;
166
+ // TODO: could just make this a div perhaps, but keep it in line with how it used to work
167
+ return < CollectionNodeClass . type ref = { itemRef } > { children } </ CollectionNodeClass . type > ;
162
168
}
163
169
164
- // TODO: changed all of these to be any, but should be node class type
165
- export function createLeafComponent < T extends object , P extends object , E extends Element > ( type : any , render : ( props : P , ref : ForwardedRef < E > ) => ReactElement | null ) : ( props : P & React . RefAttributes < T > ) => ReactElement | null ;
166
- export function createLeafComponent < T extends object , P extends object , E extends Element > ( type : any , render : ( props : P , ref : ForwardedRef < E > , node : Node < T > ) => ReactElement | null ) : ( props : P & React . RefAttributes < T > ) => ReactElement | null ;
167
- export function createLeafComponent < P extends object , E extends Element > ( type : any , render : ( props : P , ref : ForwardedRef < E > , node ?: any ) => ReactElement | null ) : ( props : P & React . RefAttributes < any > ) => ReactElement | null {
170
+ // TODO: check the signature of the CollectionNodeClass here and other places (aka useSSRCollectionNode and branchCompoennt). If I use the generic it complains. Perhaps it should be unknown? Or maybe the definitions in Listbox and stuff shouldn't use a generic?
171
+ export function createLeafComponent < T extends object , P extends object , E extends Element > ( CollectionNodeClass : CollectionNodeClass < any > , render : ( props : P , ref : ForwardedRef < E > ) => ReactElement | null ) : ( props : P & React . RefAttributes < T > ) => ReactElement | null ;
172
+ export function createLeafComponent < T extends object , P extends object , E extends Element > ( CollectionNodeClass : CollectionNodeClass < any > , render : ( props : P , ref : ForwardedRef < E > , node : Node < T > ) => ReactElement | null ) : ( props : P & React . RefAttributes < T > ) => ReactElement | null ;
173
+ export function createLeafComponent < P extends object , E extends Element > ( CollectionNodeClass : CollectionNodeClass < any > , render : ( props : P , ref : ForwardedRef < E > , node ?: any ) => ReactElement | null ) : ( props : P & React . RefAttributes < any > ) => ReactElement | null {
168
174
let Component = ( { node} ) => render ( node . props , node . props . ref , node ) ;
169
175
let Result = ( forwardRef as forwardRefType ) ( ( props : P , ref : ForwardedRef < E > ) => {
170
176
let focusableProps = useContext ( FocusableContext ) ;
@@ -177,7 +183,7 @@ export function createLeafComponent<P extends object, E extends Element>(type: a
177
183
}
178
184
179
185
return useSSRCollectionNode (
180
- type ,
186
+ CollectionNodeClass ,
181
187
props ,
182
188
ref ,
183
189
'children' in props ? props . children : null ,
@@ -195,12 +201,12 @@ export function createLeafComponent<P extends object, E extends Element>(type: a
195
201
return Result ;
196
202
}
197
203
198
- // TODO: changed all of these to be any, but should be node class type
199
- export function createBranchComponent < T extends object , P extends { children ?: any } , E extends Element > ( type : any , render : ( props : P , ref : ForwardedRef < E > , node : Node < T > ) => ReactElement | null , useChildren : ( props : P ) => ReactNode = useCollectionChildren ) : ( props : P & React . RefAttributes < E > ) => ReactElement | null {
204
+ // TODO: check the signature of this too
205
+ export function createBranchComponent < T extends object , P extends { children ?: any } , E extends Element > ( CollectionNodeClass : CollectionNodeClass < any > , render : ( props : P , ref : ForwardedRef < E > , node : Node < T > ) => ReactElement | null , useChildren : ( props : P ) => ReactNode = useCollectionChildren ) : ( props : P & React . RefAttributes < E > ) => ReactElement | null {
200
206
let Component = ( { node} ) => render ( node . props , node . props . ref , node ) ;
201
207
let Result = ( forwardRef as forwardRefType ) ( ( props : P , ref : ForwardedRef < E > ) => {
202
208
let children = useChildren ( props ) ;
203
- return useSSRCollectionNode ( type , props , ref , null , children , node => < Component node = { node } /> ) ?? < > </ > ;
209
+ return useSSRCollectionNode ( CollectionNodeClass , props , ref , null , children , node => < Component node = { node } /> ) ?? < > </ > ;
204
210
} ) ;
205
211
// @ts -ignore
206
212
Result . displayName = render . name ;
0 commit comments