@ainias42/react-bootstrap-mobile 0.1.8 → 0.1.10

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,4 +1,4 @@
1
- import { Override } from '../../../TypeHelpers';
1
+ import { Override } from '@ainias42/js-helper';
2
2
  import { OptionalListener } from '../../Hooks/useListener';
3
3
  import { HTMLAttributes } from 'react';
4
4
  import { RbmComponentProps } from '../../RbmComponentProps';
@@ -1,10 +1,12 @@
1
1
  import { RbmComponentProps } from '../../RbmComponentProps';
2
2
  import { InputHTMLAttributes } from 'react';
3
- export type CheckboxProps = RbmComponentProps<{
3
+ import { Override } from '@ainias42/js-helper';
4
+ import { OptionalListener } from '../../Hooks/useListener';
5
+ export type CheckboxProps<OnChangeData, OnChangeCheckedData> = RbmComponentProps<Override<InputHTMLAttributes<HTMLInputElement>, {
4
6
  label?: string;
5
7
  children?: string;
6
8
  isLabelBeforeCheckbox?: boolean;
7
- } & InputHTMLAttributes<HTMLInputElement>>;
8
- declare function Checkbox({ children, label, isLabelBeforeCheckbox, id, className, style, ...props }: CheckboxProps): JSX.Element;
9
+ } & OptionalListener<'onChange', OnChangeData> & OptionalListener<'onChangeChecked', OnChangeCheckedData, boolean>>>;
10
+ declare function Checkbox<OnChangeData, OnChangeCheckedData>({ children, label, isLabelBeforeCheckbox, id, className, style, ...props }: CheckboxProps<OnChangeData, OnChangeCheckedData>): JSX.Element;
9
11
  declare const tmp: typeof Checkbox;
10
12
  export { tmp as Checkbox };
@@ -0,0 +1,20 @@
1
+ import { RbmComponentProps } from '../../RbmComponentProps';
2
+ import { Override } from '../../../TypeHelpers';
3
+ import { InputHTMLAttributes } from 'react';
4
+ import { Listener } from '../../Hooks/useListener';
5
+ export type FileType = {
6
+ name: string;
7
+ url: string;
8
+ mimeType: string;
9
+ uploaded?: boolean;
10
+ blob?: Blob;
11
+ };
12
+ export type MultipleImageInputProps<OnChangeFilesData> = RbmComponentProps<Override<Omit<InputHTMLAttributes<HTMLInputElement>, 'defaultValue' | 'onChange'>, {
13
+ value: FileType[];
14
+ label?: string;
15
+ mimeTypes?: string[];
16
+ maxFiles?: number;
17
+ maxSizePerFile?: number;
18
+ onError?: (error: string) => void;
19
+ } & Listener<'onChangeFiles', OnChangeFilesData, FileType[]>>>;
20
+ export declare const MultipleFileInput: <OnChangeData>({ className, style, value, label, mimeTypes, maxFiles, maxSizePerFile, onError, ...otherProps }: MultipleImageInputProps<OnChangeData>) => JSX.Element;
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { RbmComponentProps } from '../RbmComponentProps';
3
2
  export declare const CONTAINER_CLASSES: {
4
3
  sm: string;
@@ -10,6 +9,4 @@ export declare const CONTAINER_CLASSES: {
10
9
  export type ContainerProps = RbmComponentProps<{
11
10
  fluid?: boolean | keyof typeof CONTAINER_CLASSES;
12
11
  }>;
13
- declare function Container({ fluid, className, children, style }: ContainerProps): JSX.Element;
14
- declare const ContainerMemo: typeof Container;
15
- export { ContainerMemo as Container };
12
+ export declare const Container: ({ fluid, className, children, style }: ContainerProps) => JSX.Element;
@@ -7,19 +7,22 @@ export type GridItemProps = RbmComponentProps<{
7
7
  lg?: number;
8
8
  xl?: number;
9
9
  xxl?: number;
10
+ print?: number;
10
11
  startXs?: number;
11
12
  startSm?: number;
12
13
  startMd?: number;
13
14
  startLg?: number;
14
15
  startXl?: number;
15
16
  startXxl?: number;
17
+ startPrint?: number;
16
18
  orderXs?: number;
17
19
  orderSm?: number;
18
20
  orderMd?: number;
19
21
  orderLg?: number;
20
22
  orderXl?: number;
21
23
  orderXxl?: number;
24
+ orderPrint?: number;
22
25
  }>;
23
- declare function GridItem({ style, children, className, __allowChildren, size, sm, md, lg, xl, xxl, startXs, startMd, startSm, startLg, startXl, startXxl, orderXs, orderSm, orderMd, orderLg, orderXxl, orderXl, }: GridItemProps): JSX.Element;
26
+ declare function GridItem({ style, children, className, __allowChildren, size, sm, md, lg, xl, xxl, print, startXs, startMd, startSm, startLg, startXl, startXxl, startPrint, orderXs, orderSm, orderMd, orderLg, orderXxl, orderXl, orderPrint, }: GridItemProps): JSX.Element;
24
27
  declare const GridItemMemo: typeof GridItem;
25
28
  export { GridItemMemo as GridItem };
@@ -1,15 +1,15 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
2
  import { Recursive } from '../TypeHelpers';
3
- type Child = Recursive<JSX.Element | undefined | null | Child[]> | false;
3
+ export type RbmChildWithoutString = Recursive<JSX.Element | undefined | null | RbmChildWithoutString[]> | false;
4
4
  export type WithNoStringProps = {
5
- children?: Child;
5
+ children?: RbmChildWithoutString;
6
6
  __allowChildren?: 'html';
7
7
  } | {
8
8
  children?: ReactNode;
9
9
  __allowChildren: 'text' | 'all';
10
10
  };
11
11
  export type WithNoStringAndChildrenProps = {
12
- children: Child;
12
+ children: RbmChildWithoutString;
13
13
  __allowChildren?: 'html';
14
14
  } | {
15
15
  children: ReactNode;
@@ -28,4 +28,3 @@ export type RbmComponentProps<SpecialProps, ChildrenProps = WithNoStringProps> =
28
28
  className?: string;
29
29
  style?: CSSProperties;
30
30
  } & SpecialProps;
31
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainias42/react-bootstrap-mobile",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Mobile React Components using Bootstrap",
5
5
  "main": "dist/bootstrapReactMobile",
6
6
  "scripts": {
@@ -81,7 +81,7 @@
81
81
  "@types/react-virtualized-auto-sizer": "^1.0.1",
82
82
  "classnames": "^2.3.1",
83
83
  "isomorphic-style-loader": "^5.3.2",
84
- "@ainias42/js-helper": ">=0.7.12",
84
+ "@ainias42/js-helper": ">=0.8.1",
85
85
  "react-color": "^2.19.3",
86
86
  "react-table": "^7.7.0",
87
87
  "react-virtualized-auto-sizer": "^1.0.7",
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { Override } from '../../../TypeHelpers';
2
+ import { Override } from '@ainias42/js-helper';
3
3
  import { OptionalListener, useListener } from '../../Hooks/useListener';
4
4
 
5
5
  import styles from './button.scss';
@@ -1,20 +1,26 @@
1
1
  import * as React from 'react';
2
2
  import { RbmComponentProps } from '../../RbmComponentProps';
3
- import { InputHTMLAttributes } from 'react';
3
+ import { ChangeEventHandler, InputHTMLAttributes, useCallback } from 'react';
4
4
 
5
5
  import styles from './checkbox.scss';
6
6
  import { withMemo } from '../../../helper/withMemo';
7
7
  import classNames from 'classnames';
8
+ import { Override } from '@ainias42/js-helper';
9
+ import { OptionalListener, useListenerWithExtractedProps } from '../../Hooks/useListener';
8
10
 
9
- export type CheckboxProps = RbmComponentProps<
10
- {
11
- label?: string;
12
- children?: string;
13
- isLabelBeforeCheckbox?: boolean;
14
- } & InputHTMLAttributes<HTMLInputElement>
11
+ export type CheckboxProps<OnChangeData, OnChangeCheckedData> = RbmComponentProps<
12
+ Override<
13
+ InputHTMLAttributes<HTMLInputElement>,
14
+ {
15
+ label?: string;
16
+ children?: string;
17
+ isLabelBeforeCheckbox?: boolean;
18
+ } & OptionalListener<'onChange', OnChangeData> &
19
+ OptionalListener<'onChangeChecked', OnChangeCheckedData, boolean>
20
+ >
15
21
  >;
16
22
 
17
- function Checkbox({
23
+ function Checkbox<OnChangeData, OnChangeCheckedData>({
18
24
  children,
19
25
  label = '',
20
26
  isLabelBeforeCheckbox = false,
@@ -22,7 +28,7 @@ function Checkbox({
22
28
  className,
23
29
  style,
24
30
  ...props
25
- }: CheckboxProps) {
31
+ }: CheckboxProps<OnChangeData, OnChangeCheckedData>) {
26
32
  // Variables
27
33
 
28
34
  // States
@@ -30,6 +36,23 @@ function Checkbox({
30
36
  // Refs
31
37
 
32
38
  // Callbacks
39
+ const [onChange, otherPropsWithoutChange] = useListenerWithExtractedProps<'onChange', OnChangeData>(
40
+ 'onChange',
41
+ props
42
+ );
43
+
44
+ const [onChangeChecked, otherPropsWithoutData] = useListenerWithExtractedProps<
45
+ 'onChangeChecked',
46
+ OnChangeCheckedData
47
+ >('onChangeChecked', otherPropsWithoutChange);
48
+
49
+ const onChangeInner = useCallback<ChangeEventHandler<HTMLInputElement>>(
50
+ (e) => {
51
+ onChangeChecked(e.target.checked);
52
+ onChange(e);
53
+ },
54
+ [onChange, onChangeChecked]
55
+ );
33
56
 
34
57
  // Effects
35
58
 
@@ -49,7 +72,13 @@ function Checkbox({
49
72
  <span className={classNames(styles.checkbox, className)} style={style}>
50
73
  <label htmlFor={id} key={id}>
51
74
  <span className={styles.label}>{preLabel}</span>
52
- <input {...props} type="checkbox" id={id} className={styles.input} />
75
+ <input
76
+ {...otherPropsWithoutData}
77
+ type="checkbox"
78
+ id={id}
79
+ className={styles.input}
80
+ onChange={onChangeInner}
81
+ />
53
82
  <span className={styles.checkmark} />
54
83
  <span className={styles.label}>{label}</span>
55
84
  </label>
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { useCallback, useRef, useState, MouseEvent } from 'react';
2
+ import { useCallback, useRef, useState, MouseEvent, useEffect, useLayoutEffect } from 'react';
3
3
  import { Color, ColorChangeHandler, ColorResult, SketchPicker } from 'react-color';
4
4
  import { OptionalListener, useListener } from '../../Hooks/useListener';
5
5
  import { withMemo } from '../../../helper/withMemo';
@@ -50,6 +50,7 @@ function ColorInput<OnChangeData>({
50
50
 
51
51
  // Refs
52
52
  const containerRef = useRef<HTMLDivElement>(null);
53
+ const modalRef = useRef<HTMLDivElement>(null);
53
54
 
54
55
  // States
55
56
  const [color, setColor] = useState<string>(value ?? defaultValue ?? '#000000FF');
@@ -89,7 +90,6 @@ function ColorInput<OnChangeData>({
89
90
  (e: MouseEvent) => {
90
91
  if (e.target === containerRef?.current) {
91
92
  setIsOpen(false);
92
- console.log('onContainerClick', colVal);
93
93
  addColor(colVal);
94
94
  onClose?.(colVal);
95
95
  }
@@ -107,6 +107,19 @@ function ColorInput<OnChangeData>({
107
107
  );
108
108
 
109
109
  // Effects
110
+ useLayoutEffect(() => {
111
+ if (!modalRef.current) {
112
+ return;
113
+ }
114
+ const dimension = modalRef.current.getBoundingClientRect();
115
+ if (dimension.right > window.innerWidth || dimension.bottom > window.innerHeight) {
116
+ const newPosition = {
117
+ x: Math.max(0, Math.min(window.innerWidth - dimension.width, position.x)),
118
+ y: Math.max(0, Math.min(window.innerHeight - dimension.height, position.y)),
119
+ };
120
+ setPosition(newPosition);
121
+ }
122
+ }, [position]);
110
123
 
111
124
  // Other
112
125
 
@@ -115,7 +128,7 @@ function ColorInput<OnChangeData>({
115
128
  <span className={styles.colorInput}>
116
129
  {isOpen ? (
117
130
  <div onClick={onContainerClick} className={styles.modalContainer} ref={containerRef}>
118
- <div className={styles.modal} style={{ top: position.y, left: position.x }}>
131
+ <div className={styles.modal} style={{ top: position.y, left: position.x }} ref={modalRef}>
119
132
  <SketchPicker
120
133
  color={colVal}
121
134
  onChange={onChange}
@@ -23,6 +23,7 @@ export type ImageInputProps<OnChangeData> = RbmComponentProps<
23
23
  >
24
24
  >;
25
25
 
26
+ // TODO use MultipleFileInput internal
26
27
  function ImageInput<OnChangeData>({
27
28
  className,
28
29
  style,
@@ -79,7 +80,7 @@ function ImageInput<OnChangeData>({
79
80
 
80
81
  return (
81
82
  // eslint-disable-next-line jsx-a11y/label-has-associated-control
82
- <label className={classNames(styles.imageInput, className)} style={style}>
83
+ <label className={classNames(styles.fileInput, className)} style={style}>
83
84
  {label ? <span>{label}</span> : null}
84
85
  <img
85
86
  src={(value ?? image)?.url}
@@ -0,0 +1,240 @@
1
+ import * as React from 'react';
2
+ import { RbmComponentProps } from '../../RbmComponentProps';
3
+ import { Override } from '../../../TypeHelpers';
4
+ import { ChangeEventHandler, DragEvent, DragEventHandler, InputHTMLAttributes, useCallback, useRef } from 'react';
5
+ import { Listener, useListenerWithExtractedProps } from '../../Hooks/useListener';
6
+
7
+ import styles from './imageInput.scss';
8
+ import { withMemo } from '../../../helper/withMemo';
9
+ import classNames from 'classnames';
10
+ import { Block } from '../../Layout/Block';
11
+ import { Text } from '../../Text/Text';
12
+ import { Flex } from '../../Layout/Flex';
13
+ import { Grow } from '../../Layout/Grow';
14
+ import { Icon } from '../../Icon/Icon';
15
+ import { faPlus, faTimesCircle } from '@fortawesome/free-solid-svg-icons';
16
+ import { Image } from '../../Image/Image';
17
+ import { Clickable } from '../../Clickable/Clickable';
18
+ import { Inline } from '../../Layout/Inline';
19
+
20
+ export type FileType = { name: string; url: string; mimeType: string; uploaded?: boolean; blob?: Blob };
21
+
22
+ export type MultipleImageInputProps<OnChangeFilesData> = RbmComponentProps<
23
+ Override<
24
+ Omit<InputHTMLAttributes<HTMLInputElement>, 'defaultValue' | 'onChange'>,
25
+ {
26
+ value: FileType[];
27
+ label?: string;
28
+ mimeTypes?: string[];
29
+ maxFiles?: number;
30
+ maxSizePerFile?: number;
31
+ onError?: (error: string) => void;
32
+ } & Listener<'onChangeFiles', OnChangeFilesData, FileType[]>
33
+ >
34
+ >;
35
+
36
+ export const MultipleFileInput = withMemo(function MultipleImageInput<OnChangeData>({
37
+ className,
38
+ style,
39
+ value,
40
+ label,
41
+ mimeTypes = ['image/*'],
42
+ maxFiles = 1,
43
+ maxSizePerFile = 1024 * 1024 * 10,
44
+ onError,
45
+ ...otherProps
46
+ }: MultipleImageInputProps<OnChangeData>) {
47
+ // Variables
48
+
49
+ // Refs
50
+ const inputRef = useRef<HTMLInputElement>(null);
51
+
52
+ // States
53
+
54
+ // Selectors
55
+
56
+ // Callbacks
57
+ const checkMimeType = useCallback(
58
+ (fileType: string) => {
59
+ return mimeTypes.some((type) => {
60
+ if (type === '*/*' || type === '*') {
61
+ return true;
62
+ }
63
+ if (type.endsWith('/*')) {
64
+ return fileType.startsWith(type.substring(0, type.length - 2));
65
+ }
66
+ return fileType === type;
67
+ });
68
+ },
69
+ [mimeTypes]
70
+ );
71
+
72
+ const [onChangeFiles, ...props] = useListenerWithExtractedProps('onChangeFiles', otherProps);
73
+ const getBase64 = useCallback((inputFiles: Blob[]) => {
74
+ const promises = inputFiles.map(
75
+ (file) =>
76
+ new Promise<string>((resolve, reject) => {
77
+ const reader = new FileReader();
78
+ reader.onload = () => {
79
+ resolve(reader.result as string);
80
+ };
81
+ reader.onerror = reject;
82
+ reader.readAsDataURL(file);
83
+ })
84
+ );
85
+ return Promise.all(promises);
86
+ }, []);
87
+
88
+ const onNewFiles = useCallback(
89
+ async (newFiles: File[]) => {
90
+ if (newFiles.length + value.length > maxFiles) {
91
+ onError?.(`Es sind nur ${maxFiles} Dateien erlaubt.`);
92
+ return;
93
+ }
94
+
95
+ if (newFiles.some((file) => file.size > maxSizePerFile)) {
96
+ onError?.(`Eine Datei ist zu groß. Jede Datei darf nur ${maxSizePerFile / 1024 / 1024}MB groß sein.`);
97
+ return;
98
+ }
99
+
100
+ if (newFiles.some((file) => !checkMimeType(file.type))) {
101
+ onError?.('Eine Datei ist im falschen Format');
102
+ return;
103
+ }
104
+
105
+ const newUrls = await getBase64(newFiles);
106
+ const newValue = newFiles.map((file, index) => ({
107
+ name: file.name,
108
+ url: newUrls[index],
109
+ mimeType: file.type,
110
+ blob: file,
111
+ }));
112
+
113
+ onChangeFiles([...value, ...newValue]);
114
+ },
115
+ [checkMimeType, getBase64, maxFiles, maxSizePerFile, onChangeFiles, onError, value]
116
+ );
117
+
118
+ const onInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
119
+ async (e) => {
120
+ if (!e.target.files || e.target.files.length === 0) {
121
+ return;
122
+ }
123
+
124
+ const newFiles = Array.from(e.target.files);
125
+ await onNewFiles(newFiles);
126
+ },
127
+ [onNewFiles]
128
+ );
129
+
130
+ const removeFile = useCallback(
131
+ (_: any, index: number) => {
132
+ if (index >= 0 && index < value.length) {
133
+ const newData = [...value];
134
+ newData.splice(index, 1);
135
+ onChangeFiles(newData);
136
+ }
137
+ },
138
+ [onChangeFiles, value]
139
+ );
140
+
141
+ const onDrop = useCallback<DragEventHandler>(
142
+ async (event) => {
143
+ event.preventDefault();
144
+
145
+ const files: File[] = [];
146
+ if (event.dataTransfer.items) {
147
+ for (let i = 0; i < event.dataTransfer.items.length; i++) {
148
+ if (event.dataTransfer.items[i].kind === 'file') {
149
+ const file = event.dataTransfer.items[i].getAsFile();
150
+ if (file) {
151
+ files.push(file);
152
+ }
153
+ }
154
+ }
155
+ } else {
156
+ for (let i = 0; i < event.dataTransfer.files.length; i++) {
157
+ files.push(event.dataTransfer.files[i]);
158
+ }
159
+ }
160
+
161
+ await onNewFiles(files);
162
+ },
163
+ [onNewFiles]
164
+ );
165
+
166
+ const onDragOver = useCallback((e: DragEvent) => e.preventDefault(), []);
167
+
168
+ // Effects
169
+
170
+ // Other
171
+
172
+ // Render Functions
173
+ const renderFile = (file: FileType) => {
174
+ if (file.mimeType.startsWith('image/')) {
175
+ return (
176
+ <Image
177
+ key={file.url}
178
+ src={file.url}
179
+ alt={file.name}
180
+ className={classNames(styles.previewImage, file.url)}
181
+ />
182
+ );
183
+ }
184
+ // TODO style
185
+ return (
186
+ <Block>
187
+ <Text>{file.name}</Text>
188
+ </Block>
189
+ );
190
+ };
191
+
192
+ return (
193
+ <label
194
+ className={classNames(styles.fileInput, className)}
195
+ style={style}
196
+ onDrop={onDrop}
197
+ onDragOver={onDragOver}
198
+ >
199
+ <Flex horizontal={true}>
200
+ {!!label && (
201
+ <Grow>
202
+ <Text>{label}</Text>
203
+ </Grow>
204
+ )}
205
+ {maxFiles > 1 && (
206
+ <Inline>
207
+ <Text>
208
+ {value.length}/{maxFiles}
209
+ </Text>
210
+ </Inline>
211
+ )}
212
+ </Flex>
213
+ <Flex horizontal={true} className={styles.previewContainer}>
214
+ {value?.map((file, index) => (
215
+ <Grow className={styles.preview} center={true} key={file.url}>
216
+ {renderFile(file)}
217
+ <Clickable className={styles.previewRemove} onClick={removeFile} onClickData={index}>
218
+ <Icon icon={faTimesCircle} />
219
+ </Clickable>
220
+ </Grow>
221
+ ))}
222
+ {value.length < maxFiles && (
223
+ <Grow className={styles.addFile} center={true} __allowChildren="html">
224
+ <Icon icon={faPlus} />
225
+ <input
226
+ {...props}
227
+ ref={inputRef}
228
+ className={styles.value}
229
+ onChange={onInputChange}
230
+ type="file"
231
+ multiple={maxFiles > 1}
232
+ accept={mimeTypes.join(', ')}
233
+ />
234
+ </Grow>
235
+ )}
236
+ </Flex>
237
+ </label>
238
+ );
239
+ },
240
+ styles);
@@ -1,18 +1,53 @@
1
- .imageInput {
1
+ .fileInput {
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  position: relative;
5
5
  cursor: pointer;
6
6
 
7
- .preview {
8
- flex: 1;
9
- object-fit: contain;
7
+ .previewContainer {
8
+ align-items: stretch;
9
+ flex-grow: 1;
10
10
 
11
- &.empty {
12
- background-color: #d3d3d3;
11
+ .preview {
12
+ position: relative;
13
+ border: 1px solid var(--border-light);
14
+
15
+ .previewRemove {
16
+ position: absolute;
17
+ top: 5px;
18
+ right: 5px;
19
+ opacity: 0;
20
+ font-size: 1.5rem;
21
+
22
+ svg {
23
+ background: white;
24
+ }
25
+ }
26
+
27
+ &:hover .previewRemove {
28
+ opacity: 0.7;
29
+ }
30
+ }
31
+
32
+ .previewImage {
33
+ width: 100%;
34
+ height: 100%;
35
+ object-fit: contain;
36
+ }
37
+
38
+ .addFile {
39
+ position: relative;
40
+ border-radius: 3px;
41
+ background-color: var(--border-light);
42
+
43
+ display: flex;
44
+ justify-content: center;
45
+ align-items: center;
46
+ font-size: 2rem;
13
47
  }
14
48
  }
15
49
 
50
+
16
51
  .value {
17
52
  position: absolute;
18
53
  top: 0;
@@ -17,7 +17,7 @@ export type ContainerProps = RbmComponentProps<{
17
17
  fluid?: boolean | keyof typeof CONTAINER_CLASSES;
18
18
  }>;
19
19
 
20
- function Container({ fluid, className, children, style }: ContainerProps) {
20
+ export const Container = withMemo(function Container({ fluid, className, children, style }: ContainerProps) {
21
21
  // Variables
22
22
 
23
23
  // Refs
@@ -50,8 +50,4 @@ function Container({ fluid, className, children, style }: ContainerProps) {
50
50
  {children}
51
51
  </div>
52
52
  );
53
- }
54
-
55
- // Need ContainerMemo for autocompletion of phpstorm
56
- const ContainerMemo = withMemo(Container, styles);
57
- export { ContainerMemo as Container };
53
+ }, styles);
@@ -13,18 +13,21 @@ export type GridItemProps = RbmComponentProps<{
13
13
  lg?: number;
14
14
  xl?: number;
15
15
  xxl?: number;
16
+ print?: number;
16
17
  startXs?: number;
17
18
  startSm?: number;
18
19
  startMd?: number;
19
20
  startLg?: number;
20
21
  startXl?: number;
21
22
  startXxl?: number;
23
+ startPrint?: number;
22
24
  orderXs?: number;
23
25
  orderSm?: number;
24
26
  orderMd?: number;
25
27
  orderLg?: number;
26
28
  orderXl?: number;
27
29
  orderXxl?: number;
30
+ orderPrint?: number;
28
31
  }>;
29
32
 
30
33
  function GridItem({
@@ -38,18 +41,21 @@ function GridItem({
38
41
  lg,
39
42
  xl,
40
43
  xxl,
44
+ print,
41
45
  startXs,
42
46
  startMd,
43
47
  startSm,
44
48
  startLg,
45
49
  startXl,
46
50
  startXxl,
51
+ startPrint,
47
52
  orderXs,
48
53
  orderSm,
49
54
  orderMd,
50
55
  orderLg,
51
56
  orderXxl,
52
57
  orderXl,
58
+ orderPrint,
53
59
  }: GridItemProps) {
54
60
  // Variables
55
61
 
@@ -69,6 +75,9 @@ function GridItem({
69
75
  if (xxl) {
70
76
  classes.push(`item-xxl-${xxl}`);
71
77
  }
78
+ if (print) {
79
+ classes.push(`item-print-${print}`);
80
+ }
72
81
 
73
82
  if (startXs) {
74
83
  classes.push(`start-xs-${startXs}`);
@@ -88,6 +97,9 @@ function GridItem({
88
97
  if (startXxl) {
89
98
  classes.push(`start-xxl-${startXxl}`);
90
99
  }
100
+ if (startPrint) {
101
+ classes.push(`start-print-${startPrint}`);
102
+ }
91
103
 
92
104
  if (orderXs) {
93
105
  classes.push(`order-xs-${orderXs}`);
@@ -107,6 +119,9 @@ function GridItem({
107
119
  if (orderXxl) {
108
120
  classes.push(`order-xxl-${orderXxl}`);
109
121
  }
122
+ if (orderPrint) {
123
+ classes.push(`order-print-${orderPrint}`);
124
+ }
110
125
 
111
126
  // Refs
112
127