@ainias42/react-bootstrap-mobile 0.2.1 → 0.2.3

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.
@@ -1,13 +1,17 @@
1
1
  import * as React from 'react';
2
+ import { ReactElement } from 'react';
2
3
  import { RbmComponentProps, WithNoChildren } from '../RbmComponentProps';
4
+ import { Flavor } from "../Flavor";
3
5
  export type ButtonDialogProps = RbmComponentProps<{
4
6
  title?: string;
5
7
  message: string;
6
8
  buttons: {
7
9
  text: string;
8
10
  callback: () => void;
11
+ flavor?: Flavor;
9
12
  }[];
13
+ extraContent?: ReactElement | null;
10
14
  }, WithNoChildren>;
11
- declare function ButtonDialog({ title, message, buttons, style, className }: ButtonDialogProps): React.JSX.Element;
15
+ declare function ButtonDialog({ title, message, buttons, style, className, extraContent }: ButtonDialogProps): React.JSX.Element;
12
16
  declare const ButtonDialogMemo: typeof ButtonDialog;
13
17
  export { ButtonDialogMemo as ButtonDialog };
@@ -1,4 +1,6 @@
1
1
  export declare enum Flavor {
2
2
  Accent = "flavor-accent",
3
- Basic = "flavor-basic"
3
+ Basic = "flavor-basic",
4
+ Destructive = "flavor-destructive",
5
+ Constructive = "flavor-constructive"
4
6
  }
@@ -8,5 +8,6 @@ export type FileInputProps<OnChangeFileData> = RbmComponentProps<Override<Omit<M
8
8
  value?: FileType;
9
9
  mimeType?: string;
10
10
  required?: boolean;
11
+ "data-test-id"?: string;
11
12
  } & Listener<'onChangeFile', OnChangeFileData, FileType | undefined>>>;
12
13
  export declare const FileInput: <OnChangeData>({ value, mimeType, required, ...otherProps }: FileInputProps<OnChangeData>) => React.JSX.Element;
@@ -14,5 +14,6 @@ export type MultipleFileInputProps<OnChangeFilesData> = RbmComponentProps<Overri
14
14
  allowOverride?: boolean;
15
15
  showDeleteButton?: boolean;
16
16
  error?: string;
17
+ "data-test-id"?: string;
17
18
  } & Listener<'onChangeFiles', OnChangeFilesData, FileType[]>>>;
18
- export declare const MultipleFileInput: <OnChangeData>({ className, style, value, label, mimeTypes, maxFiles, maxSizePerFile, allowOverride, onError, showDeleteButton, error, ...otherProps }: MultipleFileInputProps<OnChangeData>) => React.JSX.Element;
19
+ export declare const MultipleFileInput: <OnChangeData>({ className, style, value, label, mimeTypes, maxFiles, maxSizePerFile, allowOverride, onError, showDeleteButton, error, "data-test-id": testId, ...otherProps }: MultipleFileInputProps<OnChangeData>) => React.JSX.Element;
@@ -1,10 +1,8 @@
1
- import * as React from 'react';
2
1
  import { RbmComponentProps } from '../../RbmComponentProps';
3
2
  export type GridProps = RbmComponentProps<{
4
3
  columns?: number;
5
4
  rows?: number;
6
5
  useContainerWidth?: boolean;
7
6
  }>;
8
- declare function Grid({ style, children, columns, rows, useContainerWidth, className, __allowChildren }: GridProps): React.JSX.Element;
9
- declare const GridMemo: typeof Grid;
7
+ declare const GridMemo: import("../../../helper/withForwardRef").RefComponent<GridProps, HTMLDivElement>;
10
8
  export { GridMemo as Grid };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ListProps } from "./List";
3
+ export type InfiniteListProps<ItemType> = ListProps<ItemType> & {
4
+ hasNextPage: boolean;
5
+ loadNextPage: () => unknown | Promise<unknown>;
6
+ };
7
+ export declare const InfiniteList: <ItemType>({ renderItem, itemHeight, items, renderBefore, keyExtractor, hasNextPage, loadNextPage, style, className }: InfiniteListProps<ItemType>) => React.JSX.Element;
@@ -1,11 +1,13 @@
1
- import * as React from 'react';
2
1
  import { CSSProperties, ReactElement, ReactNode } from 'react';
3
2
  import { RbmComponentProps } from '../RbmComponentProps';
3
+ import { FixedSizeList, FixedSizeListProps } from 'react-window';
4
4
  export type ListProps<ItemType> = RbmComponentProps<{
5
5
  renderItem: (item: ItemType, style: CSSProperties, index: number) => ReactElement;
6
6
  itemHeight?: number;
7
7
  items: ItemType[];
8
8
  renderBefore?: (item: ItemType, index: number) => ReactNode;
9
9
  keyExtractor?: (item: ItemType, index: number) => string;
10
+ onItemsRendered?: FixedSizeListProps<ItemType>['onItemsRendered'];
11
+ autoSizeClassName?: string;
10
12
  }>;
11
- export declare const List: <ItemType>({ items, renderItem, itemHeight: initialItemHeight, className, style, }: ListProps<ItemType>) => React.JSX.Element;
13
+ export declare const List: import("../../helper/withForwardRef").RefComponent<ListProps<unknown>, FixedSizeList<unknown>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainias42/react-bootstrap-mobile",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Mobile React Components using Bootstrap",
5
5
  "main": "dist/bootstrapReactMobile",
6
6
  "scripts": {
@@ -1,19 +1,27 @@
1
1
  import * as React from 'react';
2
+ import { ReactElement } from 'react';
2
3
  import { withMemo } from '../../helper/withMemo';
3
4
  import { Block } from '../Layout/Block';
4
- import { Text } from '../Text/Text';
5
+ import { Text, TEXT_SIZE } from '../Text/Text';
5
6
  import { Clickable } from '../Clickable/Clickable';
6
7
 
7
8
  import styles from './buttonDialog.scss';
8
9
  import { RbmComponentProps, WithNoChildren } from '../RbmComponentProps';
9
10
  import classNames from 'classnames';
11
+ import { Flavor } from "../Flavor";
12
+ import { Size } from "../../Size";
10
13
 
11
14
  export type ButtonDialogProps = RbmComponentProps<
12
- { title?: string; message: string; buttons: { text: string; callback: () => void }[] },
15
+ {
16
+ title?: string;
17
+ message: string;
18
+ buttons: { text: string; callback: () => void, flavor?: Flavor }[]
19
+ extraContent?: ReactElement|null
20
+ },
13
21
  WithNoChildren
14
22
  >;
15
23
 
16
- function ButtonDialog({ title, message, buttons, style, className }: ButtonDialogProps) {
24
+ function ButtonDialog({ title, message, buttons, style, className, extraContent }: ButtonDialogProps) {
17
25
  // Variables
18
26
 
19
27
  // Refs
@@ -31,20 +39,21 @@ function ButtonDialog({ title, message, buttons, style, className }: ButtonDialo
31
39
  // Render Functions
32
40
 
33
41
  return (
34
- <Block className={classNames(styles.buttonDialog, className)} style={style}>
42
+ <Block className={classNames(styles.buttonDialog, className)} style={style} >
35
43
  {!!title && (
36
- <Block className={styles.title}>
37
- <Text>{title}</Text>
44
+ <Block>
45
+ <Text size={TEXT_SIZE.large} className={styles.title}>{title}</Text>
38
46
  </Block>
39
47
  )}
40
- <Block className={styles.message}>
41
- <Text>{message}</Text>
48
+ <Block>
49
+ <Text className={styles.message}>{message}</Text>
42
50
  </Block>
51
+ {extraContent}
43
52
  <Block className={styles.buttonContainer}>
44
53
  {buttons.map((b, i) => (
45
54
  // eslint-disable-next-line react/no-array-index-key
46
- <Clickable onClick={b.callback} className={styles.button} key={i + b.text}>
47
- <Text>{b.text}</Text>
55
+ <Clickable onClick={b.callback} className={classNames(styles.button)} key={i + b.text}>
56
+ <Text className={classNames(styles.buttonText, b.flavor ?? Flavor.Accent)}>{b.text}</Text>
48
57
  </Clickable>
49
58
  ))}
50
59
  </Block>
@@ -11,6 +11,7 @@ export type ConfirmDialogProps = {
11
11
  confirmText?: string;
12
12
  };
13
13
 
14
+ // TODO Translation
14
15
  function ConfirmDialog({ title, message, close, cancelText = 'Cancel', confirmText = 'OK' }: ConfirmDialogProps) {
15
16
  // Variables
16
17
  const buttons = useMemo(
@@ -1,5 +1,6 @@
1
1
  @import "../../scss/variables";
2
2
  @import "../../scss/designMixin";
3
+ @import "../../scss/flavorMixin";
3
4
 
4
5
  .buttonDialog {
5
6
  font-weight: 400;
@@ -18,8 +19,13 @@
18
19
  width: 100%;
19
20
 
20
21
  .button {
21
- color: var(--flavor-accent);
22
22
  padding: 0 8px;
23
+
24
+ .buttonText {
25
+ @include flavorSelection(--text-primary-default-color);
26
+
27
+ }
28
+
23
29
  }
24
30
  }
25
31
 
@@ -51,15 +57,18 @@
51
57
  display: block;
52
58
  border-left: 1px solid var(--border-light);
53
59
  border-top: 1px solid var(--border-light);
54
- text-overflow: ellipsis;
55
- letter-spacing: 0;
56
60
  vertical-align: middle;
57
- font-size: 16px;
58
61
  text-align: center;
59
62
  height: 44px;
60
- line-height: 44px;
61
63
  overflow: hidden;
62
64
 
65
+ .buttonText {
66
+ line-height: 44px;
67
+ text-overflow: ellipsis;
68
+ letter-spacing: 0;
69
+ font-size: 16px;
70
+ }
71
+
63
72
  &:first-child {
64
73
  border-left: none;
65
74
  }
@@ -102,12 +111,15 @@
102
111
  width: auto;
103
112
  float: right;
104
113
  border-radius: 2px;
105
- font-size: 14px;
106
- font-weight: 500;
107
114
  height: 36px;
108
- line-height: 36px;
109
115
  margin: 8px 8px 8px 0;
110
116
  min-width: 50px;
117
+
118
+ .buttonText {
119
+ line-height: 36px;
120
+ font-size: 14px;
121
+ font-weight: 500;
122
+ }
111
123
  }
112
124
  }
113
125
  }
@@ -1,4 +1,6 @@
1
1
  export enum Flavor {
2
2
  Accent = "flavor-accent",
3
3
  Basic = "flavor-basic",
4
+ Destructive = "flavor-destructive",
5
+ Constructive = "flavor-constructive",
4
6
  }
@@ -1,25 +1,24 @@
1
1
  import * as React from 'react';
2
- import {RbmComponentProps} from '../../../RbmComponentProps';
3
- import {Override} from '../../../../TypeHelpers';
4
- import {useCallback, useMemo} from 'react';
5
- import {Listener, useListenerWithExtractedProps} from '../../../Hooks/useListener';
6
-
2
+ import { RbmComponentProps } from '../../../RbmComponentProps';
3
+ import { Override } from '../../../../TypeHelpers';
4
+ import { useCallback, useMemo } from 'react';
5
+ import { Listener, useListenerWithExtractedProps } from '../../../Hooks/useListener';
7
6
  import styles from './fileInput.scss';
8
- import {withMemo} from '../../../../helper/withMemo';
9
- import {FileType} from "./FileType";
10
- import {MultipleFileInput, MultipleFileInputProps} from "./MultipleFileInput";
7
+ import { withMemo } from '../../../../helper/withMemo';
8
+ import { FileType } from "./FileType";
9
+ import { MultipleFileInput, MultipleFileInputProps } from "./MultipleFileInput";
11
10
 
12
11
 
13
12
  export type FileInputProps<OnChangeFileData> = RbmComponentProps<
14
13
  Override<
15
- Omit<MultipleFileInputProps<unknown>, "onChangeFiles" | "maxFiles" | "onChangeFilesData" | "mimeTypes"|"showDeleteButton">, {
14
+ Omit<MultipleFileInputProps<unknown>, "onChangeFiles" | "maxFiles" | "onChangeFilesData" | "mimeTypes" | "showDeleteButton">, {
16
15
  value?: FileType,
17
16
  mimeType?: string,
18
17
  required?: boolean,
18
+ "data-test-id"?: string;
19
19
  } & Listener<'onChangeFile', OnChangeFileData, FileType | undefined>>
20
20
  >;
21
21
 
22
- // TODO use MultipleFileInput internal
23
22
  export const FileInput = withMemo(function FileInput<OnChangeData>({
24
23
  value,
25
24
  mimeType,
@@ -1,21 +1,21 @@
1
1
  import * as React from 'react';
2
- import {RbmComponentProps} from '../../../RbmComponentProps';
3
- import {Override} from '../../../../TypeHelpers';
4
- import {ChangeEventHandler, DragEvent, InputHTMLAttributes, useCallback, useRef} from 'react';
5
- import {Listener, useListenerWithExtractedProps} from '../../../Hooks/useListener';
2
+ import { RbmComponentProps } from '../../../RbmComponentProps';
3
+ import { Override } from '../../../../TypeHelpers';
4
+ import { ChangeEventHandler, DragEvent, InputHTMLAttributes, useCallback, useRef } from 'react';
5
+ import { Listener, useListenerWithExtractedProps } from '../../../Hooks/useListener';
6
6
  import styles from './fileInput.scss';
7
- import {withMemo} from '../../../../helper/withMemo';
7
+ import { withMemo } from '../../../../helper/withMemo';
8
8
  import classNames from 'classnames';
9
- import {Block} from '../../../Layout/Block';
10
- import {Text} from '../../../Text/Text';
11
- import {Flex} from '../../../Layout/Flex';
12
- import {Grow} from '../../../Layout/Grow';
13
- import {Icon} from '../../../Icon/Icon';
14
- import {faFile, faPlus, faTimesCircle} from '@fortawesome/free-solid-svg-icons';
15
- import {Image} from '../../../Image/Image';
16
- import {Clickable} from '../../../Clickable/Clickable';
17
- import {Inline} from '../../../Layout/Inline';
18
- import {FileType} from "./FileType";
9
+ import { Block } from '../../../Layout/Block';
10
+ import { Text } from '../../../Text/Text';
11
+ import { Flex } from '../../../Layout/Flex';
12
+ import { Grow } from '../../../Layout/Grow';
13
+ import { Icon } from '../../../Icon/Icon';
14
+ import { faFile, faPlus, faTimesCircle } from '@fortawesome/free-solid-svg-icons';
15
+ import { Image } from '../../../Image/Image';
16
+ import { Clickable } from '../../../Clickable/Clickable';
17
+ import { Inline } from '../../../Layout/Inline';
18
+ import { FileType } from "./FileType";
19
19
  import { InlineBlock } from "../../../Layout/InlineBlock";
20
20
 
21
21
 
@@ -32,6 +32,7 @@ export type MultipleFileInputProps<OnChangeFilesData> = RbmComponentProps<
32
32
  allowOverride?: boolean
33
33
  showDeleteButton?: boolean
34
34
  error?: string,
35
+ "data-test-id"?: string;
35
36
  } & Listener<'onChangeFiles', OnChangeFilesData, FileType[]>
36
37
  >
37
38
  >;
@@ -47,7 +48,8 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
47
48
  allowOverride = maxFiles === 1,
48
49
  onError,
49
50
  showDeleteButton = true,
50
- error,
51
+ error,
52
+ "data-test-id": testId,
51
53
  ...otherProps
52
54
  }: MultipleFileInputProps<OnChangeData>) {
53
55
  // Variables
@@ -78,7 +80,7 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
78
80
  [mimeTypes]
79
81
  );
80
82
 
81
- const [onChangeFiles, ...props] = useListenerWithExtractedProps('onChangeFiles', otherProps);
83
+ const [onChangeFiles, props] = useListenerWithExtractedProps('onChangeFiles', otherProps);
82
84
  const getBase64 = useCallback((inputFiles: Blob[]) => {
83
85
  const promises = inputFiles.map(
84
86
  (file) =>
@@ -220,6 +222,7 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
220
222
  <span
221
223
  className={classNames(styles.fileInput, className)}
222
224
  style={style}
225
+ data-test-id={testId}
223
226
  >
224
227
  <Flex horizontal={true}>
225
228
  {!!label && (
@@ -248,13 +251,15 @@ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeDa
248
251
  >
249
252
  {renderFile(file)}
250
253
  {showDeleteButton &&
251
- <Clickable className={styles.previewRemove} onClick={removeFile} onClickData={index}>
254
+ <Clickable className={styles.previewRemove} onClick={removeFile}
255
+ onClickData={index}>
252
256
  <Icon icon={faTimesCircle}/>
253
257
  </Clickable>}
254
258
  </Clickable>
255
259
  </Grow>;
256
260
  })}
257
- <Grow className={classNames(styles.addFile, {[styles.hidden]: value.length >= maxFiles})} center={true}>
261
+ <Grow className={classNames(styles.addFile, {[styles.hidden]: value.length >= maxFiles})}
262
+ center={true}>
258
263
  <Clickable
259
264
  className={styles.addFileButton}
260
265
  onDrop={onDrop}
@@ -19,6 +19,7 @@ import { useOnChangeDone } from '../hooks/useOnChangeDone';
19
19
  import { InlineBlock } from "../../Layout/InlineBlock";
20
20
  import { Text } from "../../Text/Text";
21
21
  import { useSendFormContext } from "../Controller/SendFormContext";
22
+ import { useDebounced } from "../../Hooks/useDebounced";
22
23
 
23
24
  export type InputProps<OnChangeData, OnBlurData, OnChangeDoneData> = RbmComponentProps<
24
25
  Override<
@@ -119,10 +120,12 @@ export const Input = withForwardRef(function Input<OnChangeData, OnBlurData, OnC
119
120
  otherPropsWithoutOnchange
120
121
  );
121
122
 
122
- const [onChangeDone, otherPropsWithoutData] = useListenerWithExtractedProps<'onChangeDone', OnChangeDoneData>(
123
+ const [onChangeDoneWithoutDeboune, otherPropsWithoutData] = useListenerWithExtractedProps<'onChangeDone', OnChangeDoneData>(
123
124
  'onChangeDone',
124
125
  otherPropsWithoutBlur
125
126
  );
127
+ const onChangeDone = useDebounced(onChangeDoneWithoutDeboune, [onChangeDoneWithoutDeboune]);
128
+
126
129
 
127
130
  const realOnKeyDown = useCallback(
128
131
  (e: KeyboardEvent<HTMLInputElement>) => {
@@ -156,7 +159,7 @@ export const Input = withForwardRef(function Input<OnChangeData, OnBlurData, OnC
156
159
  }
157
160
  }
158
161
  },
159
- [onKeyDown, onChange, otherProps]
162
+ [onKeyDown, onEnter, otherProps.type, otherProps.step, otherProps.max, otherProps.min, onChange]
160
163
  );
161
164
 
162
165
  // Effects
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
- import { withMemo } from '../../../helper/withMemo';
3
2
  import { RbmComponentProps } from '../../RbmComponentProps';
4
3
  import { Block } from '../Block';
5
4
  import classNames from 'classnames';
6
5
  import styles from './grid.scss';
7
- import { useMemo } from 'react';
6
+ import { ForwardedRef, useMemo } from 'react';
7
+ import { withForwardRef } from "../../../helper/withForwardRef";
8
8
 
9
9
  export type GridProps = RbmComponentProps<{
10
10
  columns?: number;
@@ -12,7 +12,7 @@ export type GridProps = RbmComponentProps<{
12
12
  useContainerWidth?: boolean;
13
13
  }>;
14
14
 
15
- function Grid({ style, children, columns = 12, rows = 1, useContainerWidth = false, className, __allowChildren }: GridProps) {
15
+ function Grid({ style, children, columns = 12, rows = 1, useContainerWidth = false, className, __allowChildren }: GridProps, ref?:ForwardedRef<HTMLDivElement>) {
16
16
  // Variables
17
17
  const appliedStyle = useMemo(
18
18
  () => ({
@@ -39,6 +39,7 @@ function Grid({ style, children, columns = 12, rows = 1, useContainerWidth = fal
39
39
 
40
40
  return (
41
41
  <Block
42
+ ref={ref}
42
43
  style={appliedStyle}
43
44
  className={classNames(styles.grid, className, {[styles.useContainerWidth]: useContainerWidth})}
44
45
  __allowChildren={__allowChildren as 'all'}
@@ -49,5 +50,5 @@ function Grid({ style, children, columns = 12, rows = 1, useContainerWidth = fal
49
50
  }
50
51
 
51
52
  // Need RowMemo for autocompletion of phpstorm
52
- const GridMemo = withMemo(Grid, styles);
53
+ const GridMemo = withForwardRef(Grid, styles);
53
54
  export { GridMemo as Grid };
@@ -0,0 +1,57 @@
1
+ import React, { CSSProperties, ReactElement, ReactNode, useCallback, useState } from 'react';
2
+ import InfiniteLoader from "react-window-infinite-loader";
3
+ import { RbmComponentProps } from "../RbmComponentProps";
4
+ import { List, ListProps } from "./List";
5
+ import { withMemo } from "../../helper/withMemo";
6
+
7
+ export type InfiniteListProps<ItemType> = ListProps<ItemType> &{
8
+ hasNextPage: boolean,
9
+ loadNextPage: () => unknown | Promise<unknown>,
10
+ };
11
+
12
+ export const InfiniteList = withMemo(function InfiniteList<ItemType>({
13
+ renderItem,
14
+ itemHeight,
15
+ items,
16
+ renderBefore,
17
+ keyExtractor,
18
+ hasNextPage,
19
+ loadNextPage,
20
+ style,
21
+ className
22
+ }: InfiniteListProps<ItemType>) {
23
+ // Refs
24
+
25
+ // States/Variables/Selectors
26
+ const [isPageLoading, setIsPageLoading] = useState(false);
27
+
28
+ // Dispatch
29
+
30
+ // Callbacks
31
+ const isItemLoaded = useCallback((index: number) => !hasNextPage || index < items.length, [hasNextPage, items]);
32
+
33
+ const loadMore = useCallback(async () => {
34
+ if (!isPageLoading) {
35
+ setIsPageLoading(true);
36
+ try {
37
+ loadNextPage()
38
+ } finally {
39
+ setIsPageLoading(false);
40
+ }
41
+ }
42
+ }, [isPageLoading, loadNextPage])
43
+
44
+ // Effects
45
+
46
+ // Other
47
+
48
+ // RenderFunctions
49
+
50
+ return <InfiniteLoader isItemLoaded={isItemLoaded} loadMoreItems={loadMore}
51
+ itemCount={hasNextPage ? items.length + 1 : items.length}>{({onItemsRendered, ref}) => (
52
+ <List
53
+ items={items} renderItem={renderItem} style={style} className={className} itemHeight={itemHeight}
54
+ renderBefore={renderBefore} keyExtractor={keyExtractor} ref={ref} onItemsRendered={onItemsRendered}/>
55
+ )}
56
+ </InfiniteLoader>;
57
+ });
@@ -1,12 +1,13 @@
1
1
  import * as React from 'react';
2
- import { ComponentType, CSSProperties, ReactElement, ReactNode, useCallback, useState } from 'react';
2
+ import { ComponentType, CSSProperties, ForwardedRef, ReactElement, ReactNode, useCallback, useState } from 'react';
3
3
  import { RbmComponentProps } from '../RbmComponentProps';
4
4
 
5
5
  import styles from './list.scss';
6
6
  import { withMemo } from '../../helper/withMemo';
7
- import { FixedSizeList, ListChildComponentProps } from 'react-window';
7
+ import { FixedSizeList, FixedSizeListProps, ListChildComponentProps } from 'react-window';
8
8
  import AutoSizer from 'react-virtualized-auto-sizer';
9
9
  import { SizeCalculator, SizeCalculatorProps } from '../SizeCalculator/SizeCalculator';
10
+ import { withForwardRef } from "../../helper/withForwardRef";
10
11
 
11
12
  export type ListProps<ItemType> = RbmComponentProps<{
12
13
  renderItem: (item: ItemType, style: CSSProperties, index: number) => ReactElement;
@@ -14,15 +15,19 @@ export type ListProps<ItemType> = RbmComponentProps<{
14
15
  items: ItemType[];
15
16
  renderBefore?: (item: ItemType, index: number) => ReactNode;
16
17
  keyExtractor?: (item: ItemType, index: number) => string;
18
+ onItemsRendered?: FixedSizeListProps<ItemType>['onItemsRendered'];
19
+ autoSizeClassName?: string;
17
20
  }>;
18
21
 
19
- export const List = withMemo(function List<ItemType>({
22
+ export const List = withForwardRef(function List<ItemType>({
20
23
  items,
21
24
  renderItem,
22
25
  itemHeight: initialItemHeight = 0,
23
26
  className,
24
27
  style,
25
- }: ListProps<ItemType>) {
28
+ onItemsRendered,
29
+ autoSizeClassName,
30
+ }: ListProps<ItemType>, ref: ForwardedRef<FixedSizeList<ItemType>>) {
26
31
  // Variables
27
32
 
28
33
  // States
@@ -45,7 +50,7 @@ export const List = withMemo(function List<ItemType>({
45
50
  // Render Functions
46
51
 
47
52
  return (
48
- <AutoSizer>
53
+ <AutoSizer className={autoSizeClassName}>
49
54
  {({ height, width }: { height?: number; width?: number }) => {
50
55
  return (
51
56
  <>
@@ -54,6 +59,8 @@ export const List = withMemo(function List<ItemType>({
54
59
  {renderItem(
55
60
  items[0],
56
61
  {
62
+ visibility: 'hidden',
63
+ pointerEvents: 'none',
57
64
  position: 'relative',
58
65
  top: '0px',
59
66
  left: '0px',
@@ -66,6 +73,8 @@ export const List = withMemo(function List<ItemType>({
66
73
  )}
67
74
  {height !== undefined && width !== undefined && (
68
75
  <FixedSizeList
76
+ onItemsRendered={onItemsRendered}
77
+ ref={ref}
69
78
  height={height}
70
79
  itemCount={items.length}
71
80
  width={width}
@@ -7,4 +7,10 @@
7
7
  &:global(.flavor-basic) {
8
8
  #{$varName}: var(--flavor-basic);
9
9
  }
10
+ &:global(.flavor-destructive) {
11
+ #{$varName}: var(--flavor-destructive);
12
+ }
13
+ &:global(.flavor-constructive) {
14
+ #{$varName}: var(--flavor-constructive);
15
+ }
10
16
  }