@@ -215,14 +215,48 @@ export const FilterListBox = forwardRef(function FilterListBox<
215215 headerStyles,
216216 footerStyles,
217217 listBoxStyles,
218- children,
218+ items,
219+ children : renderChildren ,
219220 onEscape,
220221 isCheckable,
221222 onOptionClick,
222223 selectionMode = 'single' ,
223224 ...otherProps
224225 } = props ;
225226
227+ // Preserve the original `children` (may be a render function) before we
228+ // potentially overwrite it.
229+ let children : ReactNode = renderChildren as ReactNode ;
230+
231+ const renderFn = renderChildren as unknown ;
232+
233+ if ( items && typeof renderFn === 'function' ) {
234+ try {
235+ const itemsArray = Array . from ( items as Iterable < any > ) ;
236+ // Execute the render function for each item to obtain <Item/> / <Section/> nodes.
237+ children = itemsArray . map ( ( item , idx ) => {
238+ const rendered = ( renderFn as ( it : any ) => ReactNode ) ( item ) ;
239+ // Ensure every element has a stable key: rely on the user-provided key
240+ // inside the render function, otherwise fall back to the item itself or
241+ // the index. This mirrors React Aria examples where the render function
242+ // is expected to set keys, but we add a fallback for robustness.
243+ if (
244+ React . isValidElement ( rendered ) &&
245+ ( rendered as ReactElement ) . key == null
246+ ) {
247+ return React . cloneElement ( rendered as ReactElement , {
248+ key : ( rendered as any ) ?. key ?? item ?. key ?? idx ,
249+ } ) ;
250+ }
251+
252+ return rendered as ReactNode ;
253+ } ) ;
254+ } catch {
255+ // If conversion fails for some reason, we silently ignore and proceed
256+ // with the original children value so we don't break runtime.
257+ }
258+ }
259+
226260 // Collect original option keys to avoid duplicating them as custom values.
227261 const originalKeys = useMemo ( ( ) => {
228262 const keys = new Set < string > ( ) ;
@@ -881,6 +915,7 @@ export const FilterListBox = forwardRef(function FilterListBox<
881915 mods = { mods }
882916 size = { size }
883917 isCheckable = { isCheckable }
918+ items = { items as any }
884919 onSelectionChange = { handleSelectionChange }
885920 onEscape = { onEscape }
886921 onOptionClick = { handleOptionClick }
0 commit comments