@noya-app/noya-designsystem 0.1.64 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.turbo/turbo-build.log +13 -10
  2. package/CHANGELOG.md +12 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +501 -228
  5. package/dist/index.d.ts +501 -228
  6. package/dist/index.js +6738 -2571
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +6697 -2499
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +6 -6
  11. package/src/components/ActivityIndicator.tsx +9 -4
  12. package/src/components/ActivityLog.tsx +197 -0
  13. package/src/components/AnimatePresence.tsx +37 -22
  14. package/src/components/Avatar.tsx +42 -25
  15. package/src/components/Banner.tsx +57 -11
  16. package/src/components/BaseToolbar.tsx +29 -7
  17. package/src/components/Breadcrumbs.tsx +2 -2
  18. package/src/components/Button.tsx +23 -24
  19. package/src/components/Checkbox.tsx +6 -35
  20. package/src/components/Chip.tsx +45 -33
  21. package/src/components/Collection.tsx +16 -11
  22. package/src/components/ColorSwatch.tsx +3 -3
  23. package/src/components/ColorSwatchControl.tsx +2 -2
  24. package/src/components/Combobox.tsx +6 -6
  25. package/src/components/ComboboxMenu.tsx +6 -5
  26. package/src/components/CommandPalette.tsx +1 -1
  27. package/src/components/Dialog.tsx +6 -12
  28. package/src/components/Divider.tsx +8 -8
  29. package/src/components/DraggableMenuButton.tsx +9 -5
  30. package/src/components/Drawer.tsx +5 -5
  31. package/src/components/DropdownMenu.tsx +1 -1
  32. package/src/components/EditableText.tsx +2 -2
  33. package/src/components/Fade.tsx +13 -13
  34. package/src/components/FileUploadIndicator.tsx +11 -11
  35. package/src/components/FloatingWindow.tsx +2 -2
  36. package/src/components/Grid.tsx +18 -11
  37. package/src/components/GridView.tsx +32 -25
  38. package/src/components/IVirtualizedList.tsx +5 -0
  39. package/src/components/Icons.tsx +24 -4
  40. package/src/components/InputField.tsx +19 -19
  41. package/src/components/InspectorContainer.tsx +2 -2
  42. package/src/components/InspectorPrimitives.tsx +15 -9
  43. package/src/components/Label.tsx +4 -3
  44. package/src/components/LabeledElementView.tsx +3 -3
  45. package/src/components/LabeledField.tsx +6 -6
  46. package/src/components/List.tsx +103 -45
  47. package/src/components/ListMenu.tsx +91 -0
  48. package/src/components/ListNavigator.tsx +106 -0
  49. package/src/components/ListView.tsx +20 -1158
  50. package/src/components/MediaThumbnail.tsx +56 -15
  51. package/src/components/Message.tsx +5 -5
  52. package/src/components/Navigator.tsx +461 -0
  53. package/src/components/NoyaLogo.tsx +1 -1
  54. package/src/components/Popover.tsx +9 -5
  55. package/src/components/Progress.tsx +19 -9
  56. package/src/components/ResizableContainer.tsx +187 -0
  57. package/src/components/RingProgress.tsx +128 -0
  58. package/src/components/ScrollArea.tsx +4 -4
  59. package/src/components/ScrollableSidebar.tsx +10 -0
  60. package/src/components/SearchCompletionMenu.tsx +3 -3
  61. package/src/components/Section.tsx +107 -57
  62. package/src/components/SegmentedControl.tsx +29 -29
  63. package/src/components/SelectMenu.tsx +13 -20
  64. package/src/components/SelectionToolbar.tsx +4 -3
  65. package/src/components/Slider.tsx +9 -9
  66. package/src/components/Spacer.tsx +2 -2
  67. package/src/components/StackNavigator.tsx +378 -0
  68. package/src/components/Stepper.tsx +88 -0
  69. package/src/components/Switch.tsx +4 -4
  70. package/src/components/Tabs.tsx +3 -3
  71. package/src/components/Text.tsx +23 -13
  72. package/src/components/TextArea.tsx +3 -3
  73. package/src/components/Toast.tsx +4 -4
  74. package/src/components/Toolbar.tsx +50 -9
  75. package/src/components/ToolbarDrawer.tsx +2 -2
  76. package/src/components/Tooltip.tsx +1 -1
  77. package/src/components/TreeView.tsx +11 -4
  78. package/src/components/UserPointer.tsx +4 -4
  79. package/src/components/ai-assistant/AIAssistantLayout.tsx +8 -8
  80. package/src/components/blocks/ImageBlockComponent.tsx +13 -7
  81. package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +4 -4
  82. package/src/components/file-explorer/FileExplorerLayout.tsx +20 -8
  83. package/src/components/internal/Checkmark.tsx +1 -1
  84. package/src/components/internal/Menu.tsx +22 -18
  85. package/src/components/internal/MenuViewport.tsx +13 -6
  86. package/src/components/internal/SelectItem.tsx +3 -3
  87. package/src/components/internal/TextInput.tsx +5 -1
  88. package/src/components/listView/ListViewContexts.tsx +68 -0
  89. package/src/components/listView/ListViewEditableRowTitle.tsx +55 -0
  90. package/src/components/listView/ListViewRoot.tsx +521 -0
  91. package/src/components/listView/ListViewRow.tsx +475 -0
  92. package/src/components/listView/ListViewRowTitle.tsx +21 -0
  93. package/src/components/listView/types.ts +11 -0
  94. package/src/components/pipeline/PipelineResultLayout.tsx +6 -6
  95. package/src/components/sorting/DragRegistration.tsx +2 -1
  96. package/src/components/sorting/SharedDragProvider.tsx +91 -9
  97. package/src/components/sorting/Sortable.tsx +71 -17
  98. package/src/components/workspace/DrawerWorkspaceLayout.tsx +5 -5
  99. package/src/components/workspace/PanelWorkspaceLayout.tsx +65 -49
  100. package/src/components/workspace/VerticalTabMenu.tsx +25 -15
  101. package/src/components/workspace/WorkspaceLayout.tsx +30 -21
  102. package/src/contexts/DialogContext.tsx +17 -5
  103. package/src/hooks/useIndent.ts +3 -8
  104. package/src/index.css +24 -10
  105. package/src/index.tsx +10 -5
  106. package/src/utils/classNames.ts +52 -6
  107. package/src/utils/editableBlockStyles.ts +2 -2
  108. package/src/utils/formatByteSize.ts +1 -0
  109. package/src/utils/inputs.ts +8 -6
  110. package/src/utils/sketchColor.ts +0 -34
  111. package/tailwind.config.ts +1 -0
  112. package/src/components/FillInputField.tsx +0 -37
  113. package/src/components/FillPreviewBackground.tsx +0 -134
  114. package/src/components/GradientPicker.tsx +0 -90
  115. package/src/utils/getGradientBackground.tsx +0 -31
@@ -0,0 +1,521 @@
1
+ "use client";
2
+
3
+ import { Size } from "@noya-app/noya-geometry";
4
+ import { range } from "@noya-app/noya-utils";
5
+ import { forwardRefGeneric, memoGeneric } from "@noya-app/react-utils";
6
+ import React, {
7
+ CSSProperties,
8
+ ForwardedRef,
9
+ isValidElement,
10
+ memo,
11
+ ReactElement,
12
+ ReactNode,
13
+ useCallback,
14
+ useContext,
15
+ useImperativeHandle,
16
+ useLayoutEffect,
17
+ useMemo,
18
+ useRef,
19
+ } from "react";
20
+ import { WindowScroller, WindowScrollerChildProps } from "react-virtualized";
21
+ import { ListChildComponentProps, VariableSizeList } from "react-window";
22
+ import { INPUT_HEIGHT } from "../../theme";
23
+ import { mergeConflictingClassNames } from "../../utils/classNames";
24
+ import { IVirtualizedList } from "../IVirtualizedList";
25
+ import { ScrollArea } from "../ScrollArea";
26
+ import { SharedDragProps } from "../sorting/DragRegistration";
27
+ import { Sortable } from "../sorting/Sortable";
28
+ import {
29
+ DropValidator,
30
+ MoveDragItemHandler,
31
+ SortableItemContextProps,
32
+ } from "../sorting/sorting";
33
+ import {
34
+ ListRowContext,
35
+ ListRowContextValue,
36
+ ListViewContext,
37
+ ListViewContextValue,
38
+ ListViewDraggingContext,
39
+ ListViewDraggingContextValue,
40
+ RenderItemContext,
41
+ } from "./ListViewContexts";
42
+ import {
43
+ ListColorScheme,
44
+ ListRowMarginType,
45
+ ListRowPosition,
46
+ ListViewSectionHeaderVariant,
47
+ ListViewVariant,
48
+ PressEventName,
49
+ } from "./types";
50
+
51
+ export const ROW_HEIGHT = 31;
52
+ export const SECTION_HEADER_LABEL_HEIGHT = INPUT_HEIGHT;
53
+
54
+ const VirtualizedListRow = memo(function VirtualizedListRow({
55
+ index,
56
+ style,
57
+ }: ListChildComponentProps) {
58
+ const renderItem = useContext(RenderItemContext);
59
+
60
+ return (
61
+ <div key={index} style={style}>
62
+ {renderItem(index)}
63
+ </div>
64
+ );
65
+ });
66
+
67
+ /* ----------------------------------------------------------------------------
68
+ * VirtualizedList
69
+ * ------------------------------------------------------------------------- */
70
+
71
+ interface VirtualizedListProps<T> {
72
+ size: Size;
73
+ scrollElement: HTMLDivElement;
74
+ items: T[];
75
+ getItemHeight: (index: number) => number;
76
+ keyExtractor: (index: number) => string;
77
+ renderItem: (index: number) => ReactNode;
78
+ }
79
+
80
+ const VirtualizedListInner = forwardRefGeneric(function VirtualizedListInner<T>(
81
+ {
82
+ size,
83
+ scrollElement,
84
+ items,
85
+ getItemHeight,
86
+ keyExtractor,
87
+ renderItem,
88
+ }: VirtualizedListProps<T>,
89
+ ref: ForwardedRef<IVirtualizedList>
90
+ ) {
91
+ const listRef = useRef<VariableSizeList<T> | null>(null);
92
+
93
+ useImperativeHandle(ref, () => ({
94
+ scrollToIndex(index) {
95
+ listRef.current?.scrollToItem(index);
96
+ },
97
+ }));
98
+
99
+ useLayoutEffect(() => {
100
+ listRef.current?.resetAfterIndex(0);
101
+ }, [
102
+ // When items change, we need to re-render the virtualized list,
103
+ // since it doesn't currently support row height changes
104
+ items,
105
+ ]);
106
+
107
+ // Internally, react-virtualized updates these properties. We always want
108
+ // to use our custom scroll element, so we override them. It may update
109
+ // overflowX/Y individually in addition to `overflow`, so we include all 3.
110
+ const listStyle = useMemo(
111
+ (): CSSProperties => ({
112
+ overflowX: "initial",
113
+ overflowY: "initial",
114
+ overflow: "initial",
115
+ }),
116
+ []
117
+ );
118
+
119
+ return (
120
+ <RenderItemContext.Provider value={renderItem}>
121
+ <WindowScroller
122
+ scrollElement={scrollElement}
123
+ style={useMemo(() => ({ flex: "1 1 auto" }), [])}
124
+ >
125
+ {useCallback(
126
+ ({
127
+ registerChild,
128
+ onChildScroll,
129
+ scrollTop,
130
+ }: WindowScrollerChildProps & {
131
+ // Added when noya-designsystem moved to a separate package.
132
+ // I think this is a hack to get around the fact that react-virtualized
133
+ // doesn't update on scroll unless we force it to by changing ref.
134
+ // Either we're not using this the intended way or the types are wrong.
135
+ registerChild: (element: any) => void;
136
+ }) => (
137
+ <div ref={registerChild}>
138
+ <VariableSizeList<T>
139
+ ref={listRef}
140
+ // The list won't update on scroll unless we force it to by changing key
141
+ key={scrollTop}
142
+ style={listStyle}
143
+ itemKey={keyExtractor}
144
+ onScroll={({ scrollOffset }: { scrollOffset: number }) => {
145
+ onChildScroll({ scrollTop: scrollOffset });
146
+ }}
147
+ initialScrollOffset={scrollTop}
148
+ width={size.width}
149
+ height={size.height}
150
+ itemCount={items.length}
151
+ itemSize={getItemHeight}
152
+ estimatedItemSize={ROW_HEIGHT}
153
+ >
154
+ {VirtualizedListRow as any}
155
+ </VariableSizeList>
156
+ </div>
157
+ ),
158
+ [
159
+ listStyle,
160
+ keyExtractor,
161
+ size.width,
162
+ size.height,
163
+ items.length,
164
+ getItemHeight,
165
+ ]
166
+ )}
167
+ </WindowScroller>
168
+ </RenderItemContext.Provider>
169
+ );
170
+ });
171
+
172
+ const VirtualizedList = memo(
173
+ VirtualizedListInner
174
+ ) as typeof VirtualizedListInner;
175
+
176
+ /* ----------------------------------------------------------------------------
177
+ * Root
178
+ * ------------------------------------------------------------------------- */
179
+
180
+ export type ListViewItemInfo = {
181
+ isDragOverlay: boolean;
182
+ activeDragIndex?: number;
183
+ };
184
+
185
+ export type ListViewRootProps<T> = {
186
+ data: T[];
187
+ renderItem: (item: T, index: number, info: ListViewItemInfo) => ReactNode;
188
+ keyExtractor: (item: T, index: number) => string;
189
+ /**
190
+ * Each item must have an `id` in order to be sortable.
191
+ *
192
+ * Additionally, the key extracted with `keyExtractor` must match the ListItem.Row `id`.
193
+ */
194
+ sortable?: boolean;
195
+ virtualized?: Size;
196
+
197
+ id?: string;
198
+ className?: string;
199
+ style?: CSSProperties;
200
+ role?: string;
201
+ "aria-labelledby"?: string;
202
+ "aria-orientation"?: "vertical" | "horizontal";
203
+ "aria-multiselectable"?: boolean;
204
+ onPress?: () => void;
205
+ scrollable?: boolean;
206
+ expandable?: boolean;
207
+ onMoveItem?: MoveDragItemHandler;
208
+ indentation?: number;
209
+ acceptsDrop?: DropValidator;
210
+ pressEventName?: PressEventName;
211
+ variant?: ListViewVariant;
212
+ sectionHeaderVariant?: ListViewSectionHeaderVariant;
213
+ divider?: boolean;
214
+ gap?: number;
215
+ colorScheme?: ListColorScheme;
216
+ containerRef?: React.RefObject<HTMLDivElement | null>;
217
+ onDragOver?: React.DragEventHandler<HTMLDivElement>;
218
+ onDragEnter?: React.DragEventHandler<HTMLDivElement>;
219
+ onDragLeave?: React.DragEventHandler<HTMLDivElement>;
220
+ onDrop?: React.DragEventHandler<HTMLDivElement>;
221
+ renderEmptyState?: () => ReactNode;
222
+ getDropTargetParentIndex?: SortableItemContextProps["getDropTargetParentIndex"];
223
+ sharedDragProps?: SharedDragProps;
224
+ sortableId?: string;
225
+ itemHeight?: number;
226
+ };
227
+
228
+ export const ListViewRoot = memoGeneric(
229
+ forwardRefGeneric(function ListViewRootInner<T>(
230
+ {
231
+ id,
232
+ className,
233
+ style,
234
+ role,
235
+ "aria-labelledby": ariaLabelledby,
236
+ "aria-orientation": ariaOrientation,
237
+ "aria-multiselectable": ariaMultiselectable,
238
+ onPress,
239
+ scrollable = false,
240
+ expandable = true,
241
+ sortable = false,
242
+ divider = false,
243
+ onMoveItem,
244
+ indentation = 12,
245
+ acceptsDrop,
246
+ data,
247
+ renderItem,
248
+ keyExtractor,
249
+ virtualized,
250
+ variant = "normal",
251
+ sectionHeaderVariant = "normal",
252
+ pressEventName = "onClick",
253
+ colorScheme = "primary",
254
+ gap = 0,
255
+ containerRef,
256
+ onDragOver,
257
+ onDragEnter,
258
+ onDragLeave,
259
+ onDrop,
260
+ renderEmptyState,
261
+ getDropTargetParentIndex,
262
+ sharedDragProps,
263
+ sortableId,
264
+ itemHeight,
265
+ }: ListViewRootProps<T>,
266
+ forwardedRef: ForwardedRef<IVirtualizedList>
267
+ ) {
268
+ const handleClick = useCallback(
269
+ (event: React.MouseEvent) => {
270
+ if (
271
+ event.target instanceof HTMLElement &&
272
+ event.target.classList.contains("scroll-component")
273
+ )
274
+ return;
275
+
276
+ // As a hack, we call preventDefault in a row if the event was handled.
277
+ // If the event wasn't handled already, we call onPress here.
278
+ if (!event.isDefaultPrevented()) {
279
+ onPress?.();
280
+ }
281
+ },
282
+ [onPress]
283
+ );
284
+
285
+ const renderChild = useCallback(
286
+ (index: number) =>
287
+ renderItem(data[index], index, { isDragOverlay: false }),
288
+ [data, renderItem]
289
+ );
290
+
291
+ const defaultContextValue = useMemo(
292
+ (): ListRowContextValue => ({
293
+ marginType: "none",
294
+ selectedPosition: "only",
295
+ isSectionHeader: false,
296
+ }),
297
+ []
298
+ );
299
+
300
+ const getItemContextValue = useCallback(
301
+ (i: number): ListRowContextValue | undefined => {
302
+ if (variant === "bare" || variant === "normal")
303
+ return defaultContextValue;
304
+
305
+ const current = renderChild(i);
306
+
307
+ if (!isValidElement(current)) return;
308
+
309
+ const prevChild = i - 1 >= 0 && renderChild(i - 1);
310
+ const nextChild = i + 1 < data.length && renderChild(i + 1);
311
+
312
+ const next: ReactElement<any> | undefined = isValidElement(nextChild)
313
+ ? nextChild
314
+ : undefined;
315
+ const prev: ReactElement<any> | undefined = isValidElement(prevChild)
316
+ ? prevChild
317
+ : undefined;
318
+
319
+ const hasMarginTop = !prev;
320
+ const hasMarginBottom =
321
+ !next ||
322
+ (current as any).props.isSectionHeader ||
323
+ (next && (next as any).props.isSectionHeader);
324
+
325
+ let marginType: ListRowMarginType;
326
+
327
+ if (hasMarginTop && hasMarginBottom) {
328
+ marginType = "vertical";
329
+ } else if (hasMarginBottom) {
330
+ marginType = "bottom";
331
+ } else if (hasMarginTop) {
332
+ marginType = "top";
333
+ } else {
334
+ marginType = "none";
335
+ }
336
+
337
+ let selectedPosition: ListRowPosition = "only";
338
+
339
+ if ((current as any).props.selected) {
340
+ const nextSelected =
341
+ next && !next.props.isSectionHeader && (next as any).props.selected;
342
+ const prevSelected =
343
+ prev && !prev.props.isSectionHeader && (prev as any).props.selected;
344
+
345
+ if (nextSelected && prevSelected) {
346
+ selectedPosition = "middle";
347
+ } else if (nextSelected && !prevSelected) {
348
+ selectedPosition = "first";
349
+ } else if (!nextSelected && prevSelected) {
350
+ selectedPosition = "last";
351
+ }
352
+ }
353
+
354
+ return {
355
+ marginType,
356
+ selectedPosition,
357
+ isSectionHeader: (current as any).props.isSectionHeader,
358
+ };
359
+ },
360
+ [variant, defaultContextValue, renderChild, data.length]
361
+ );
362
+
363
+ const draggingContextOverlayValue = useMemo(
364
+ (): ListViewDraggingContextValue => ({
365
+ isDragOverlay: true,
366
+ }),
367
+ []
368
+ );
369
+
370
+ const renderOverlay = useCallback(
371
+ (index: number) => (
372
+ <div style={{ opacity: 0.25 }}>
373
+ <ListViewDraggingContext.Provider value={draggingContextOverlayValue}>
374
+ {renderItem(data[index], index, { isDragOverlay: true })}
375
+ </ListViewDraggingContext.Provider>
376
+ </div>
377
+ ),
378
+ [draggingContextOverlayValue, renderItem, data]
379
+ );
380
+
381
+ const renderWrappedChild = useCallback(
382
+ (index: number) => {
383
+ const contextValue = getItemContextValue(index);
384
+ const current = renderChild(index);
385
+
386
+ if (!contextValue || !isValidElement(current)) return null;
387
+
388
+ return (
389
+ <ListRowContext.Provider key={current.key} value={contextValue}>
390
+ {current}
391
+ </ListRowContext.Provider>
392
+ );
393
+ },
394
+ [getItemContextValue, renderChild]
395
+ );
396
+
397
+ const ids = useMemo(() => data.map(keyExtractor), [keyExtractor, data]);
398
+
399
+ const withSortable = (children: ReactNode) =>
400
+ sortable ? (
401
+ <Sortable.Root
402
+ id={sortableId}
403
+ onMoveItem={onMoveItem}
404
+ keys={ids}
405
+ renderOverlay={renderOverlay}
406
+ acceptsDrop={acceptsDrop}
407
+ getDropTargetParentIndex={getDropTargetParentIndex}
408
+ sharedDragProps={sharedDragProps}
409
+ >
410
+ {children}
411
+ </Sortable.Root>
412
+ ) : (
413
+ children
414
+ );
415
+
416
+ const withScrollable = (
417
+ children: (scrollElementRef: HTMLDivElement | null) => ReactNode
418
+ ) => (scrollable ? <ScrollArea>{children}</ScrollArea> : children(null));
419
+
420
+ const getItemHeight = useCallback(
421
+ (index: number) => {
422
+ if (itemHeight) return itemHeight;
423
+
424
+ const child = getItemContextValue(index);
425
+ const height =
426
+ child?.isSectionHeader && sectionHeaderVariant === "label"
427
+ ? SECTION_HEADER_LABEL_HEIGHT
428
+ : ROW_HEIGHT;
429
+ return height;
430
+ },
431
+ [getItemContextValue, itemHeight, sectionHeaderVariant]
432
+ );
433
+
434
+ const getKey = useCallback(
435
+ (index: number) => keyExtractor(data[index], index),
436
+ [data, keyExtractor]
437
+ );
438
+
439
+ const draggingContextValue = useMemo(() => ({}), []);
440
+ const gapStyle = useMemo(() => ({ gap: `${gap}px` }), [gap]);
441
+
442
+ const contextValue: ListViewContextValue = useMemo(
443
+ () => ({
444
+ pressEventName,
445
+ colorScheme,
446
+ gap,
447
+ sectionHeaderVariant,
448
+ variant,
449
+ divider,
450
+ sortable,
451
+ expandable,
452
+ indentation,
453
+ }),
454
+ [
455
+ pressEventName,
456
+ colorScheme,
457
+ gap,
458
+ sectionHeaderVariant,
459
+ variant,
460
+ divider,
461
+ sortable,
462
+ expandable,
463
+ indentation,
464
+ ]
465
+ );
466
+
467
+ return (
468
+ <ListViewContext.Provider value={contextValue}>
469
+ <ListViewDraggingContext.Provider value={draggingContextValue}>
470
+ <div
471
+ id={id}
472
+ role={role}
473
+ aria-labelledby={ariaLabelledby}
474
+ aria-orientation={ariaOrientation}
475
+ aria-multiselectable={ariaMultiselectable}
476
+ className={mergeConflictingClassNames(
477
+ [
478
+ `n-flex n-flex-col n-text-text-muted ${
479
+ scrollable ? "n-flex-1" : "n-flex-none"
480
+ } `,
481
+ className,
482
+ ],
483
+ {
484
+ categories: ["flex"],
485
+ }
486
+ )}
487
+ style={{ ...gapStyle, ...style }}
488
+ {...{
489
+ [pressEventName]: handleClick,
490
+ }}
491
+ ref={containerRef}
492
+ onDragOver={onDragOver}
493
+ onDragEnter={onDragEnter}
494
+ onDragLeave={onDragLeave}
495
+ onDrop={onDrop}
496
+ >
497
+ {data.length === 0 && renderEmptyState
498
+ ? renderEmptyState()
499
+ : withScrollable((scrollElementRef: HTMLDivElement | null) =>
500
+ withSortable(
501
+ virtualized ? (
502
+ <VirtualizedList<T>
503
+ ref={forwardedRef}
504
+ scrollElement={scrollElementRef!}
505
+ items={data}
506
+ size={virtualized}
507
+ getItemHeight={getItemHeight}
508
+ keyExtractor={getKey}
509
+ renderItem={renderWrappedChild}
510
+ />
511
+ ) : (
512
+ range(0, data.length).map(renderWrappedChild)
513
+ )
514
+ )
515
+ )}
516
+ </div>
517
+ </ListViewDraggingContext.Provider>
518
+ </ListViewContext.Provider>
519
+ );
520
+ })
521
+ );