@oliasoft-open-source/react-ui-library 2.3.4 → 2.4.0
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.
- package/package.json +2 -1
- package/src/components/drawer/drawer-resize-wrapper.jsx +73 -0
- package/src/components/drawer/drawer-tabs.jsx +1 -0
- package/src/components/drawer/drawer.jsx +58 -47
- package/src/components/drawer/drawer.module.less +54 -11
- package/src/components/drawer/drawer.stories.jsx +141 -1
- package/src/components/layout/flex/flex.stories.jsx +6 -1
- package/src/components/layout/grid/grid.stories.jsx +10 -8
- package/src/components/top-bar/top-bar.module.less +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oliasoft-open-source/react-ui-library",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Reusable UI components for React projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -126,6 +126,7 @@
|
|
|
126
126
|
"react-icons": "^4.2.0",
|
|
127
127
|
"react-infinite-scroll-component": "^6.1.0",
|
|
128
128
|
"react-laag": "^2.0.3",
|
|
129
|
+
"react-resizable": "^3.0.4",
|
|
129
130
|
"react-router-dom": "^5.3.0",
|
|
130
131
|
"react-svg": "^14.0.12",
|
|
131
132
|
"react-toastify": "^8.0.2",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Resizable } from 'react-resizable';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import styles from './drawer.module.less';
|
|
5
|
+
|
|
6
|
+
const ResizeHandle = React.forwardRef((props, ref) => {
|
|
7
|
+
const { handleAxis, ...rest } = props;
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={styles.resizeHandle}
|
|
12
|
+
{...rest} // eslint-disable-line react/jsx-props-no-spreading
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const DrawerResizeWrapper = ({
|
|
18
|
+
children,
|
|
19
|
+
width,
|
|
20
|
+
minWidth,
|
|
21
|
+
right,
|
|
22
|
+
onResize,
|
|
23
|
+
open,
|
|
24
|
+
}) => {
|
|
25
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
26
|
+
const MINIMUM_OPEN_WIDTH = 100;
|
|
27
|
+
const MAXIMUM_OPEN_WIDTH = window.innerWidth / 2;
|
|
28
|
+
|
|
29
|
+
const handleResize = (event, { node, size, handle }) => {
|
|
30
|
+
if (
|
|
31
|
+
open &&
|
|
32
|
+
size.width > MINIMUM_OPEN_WIDTH &&
|
|
33
|
+
size.width < MAXIMUM_OPEN_WIDTH
|
|
34
|
+
) {
|
|
35
|
+
onResize(size.width);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return onResize ? (
|
|
40
|
+
<Resizable
|
|
41
|
+
width={width}
|
|
42
|
+
height={100} // Arbitrary height value. It's required by react-resizable even if height not adjustable but doesn't actually do anything in this case
|
|
43
|
+
minConstraints={[minWidth, null]}
|
|
44
|
+
onResize={handleResize}
|
|
45
|
+
handle={open ? <ResizeHandle /> : null}
|
|
46
|
+
resizeHandles={right ? ['w'] : ['e']}
|
|
47
|
+
axis="x"
|
|
48
|
+
className={isResizing ? styles.isResizing : ''}
|
|
49
|
+
onResizeStart={() => setIsResizing(true)}
|
|
50
|
+
onResizeStop={() => setIsResizing(false)}
|
|
51
|
+
>
|
|
52
|
+
{children}
|
|
53
|
+
</Resizable>
|
|
54
|
+
) : (
|
|
55
|
+
<>{children}</>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
DrawerResizeWrapper.defaultProps = {
|
|
60
|
+
right: false,
|
|
61
|
+
width: 400,
|
|
62
|
+
minWidth: null,
|
|
63
|
+
children: null,
|
|
64
|
+
onResize: null,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
DrawerResizeWrapper.propTypes = {
|
|
68
|
+
right: PropTypes.bool,
|
|
69
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
70
|
+
minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
71
|
+
children: PropTypes.node,
|
|
72
|
+
onResize: PropTypes.func,
|
|
73
|
+
};
|
|
@@ -5,6 +5,7 @@ import { FaChevronLeft, FaChevronRight } from 'react-icons/fa';
|
|
|
5
5
|
import { Button } from '../button/button';
|
|
6
6
|
import { DrawerTabs } from './drawer-tabs';
|
|
7
7
|
import styles from './drawer.module.less';
|
|
8
|
+
import { DrawerResizeWrapper } from './drawer-resize-wrapper';
|
|
8
9
|
|
|
9
10
|
export const Drawer = ({
|
|
10
11
|
background,
|
|
@@ -23,6 +24,7 @@ export const Drawer = ({
|
|
|
23
24
|
tabs,
|
|
24
25
|
defaultTabIndex,
|
|
25
26
|
testId,
|
|
27
|
+
onResize,
|
|
26
28
|
}) => {
|
|
27
29
|
const isStandardButton = button === true;
|
|
28
30
|
const isCustomButton = !isStandardButton && isValidElement(button);
|
|
@@ -30,7 +32,8 @@ export const Drawer = ({
|
|
|
30
32
|
isStandardButton || tabs ? useState(openProp) : [openProp, null];
|
|
31
33
|
const [activeTab, setActiveTab] = useState(open ? defaultTabIndex : null);
|
|
32
34
|
const openWidth = Array.isArray(width) ? width[activeTab] : width;
|
|
33
|
-
const
|
|
35
|
+
const TABS_WIDTH = 38;
|
|
36
|
+
const currentWidth = open ? openWidth : tabs ? TABS_WIDTH : closedWidth;
|
|
34
37
|
|
|
35
38
|
const handleTabClick = (index) => {
|
|
36
39
|
if (activeTab === index) {
|
|
@@ -43,58 +46,64 @@ export const Drawer = ({
|
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
return (
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
)}
|
|
53
|
-
style={{
|
|
54
|
-
top,
|
|
55
|
-
}}
|
|
49
|
+
<DrawerResizeWrapper
|
|
50
|
+
width={currentWidth}
|
|
51
|
+
minWidth={tabs ? TABS_WIDTH : closedWidth}
|
|
52
|
+
onResize={onResize}
|
|
53
|
+
open={open}
|
|
54
|
+
right={right}
|
|
56
55
|
>
|
|
57
56
|
<div
|
|
58
|
-
className={cx(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
width={openWidth}
|
|
64
|
-
testId={testId}
|
|
65
|
-
open={open}
|
|
66
|
-
tabs={tabs}
|
|
67
|
-
activeTab={activeTab}
|
|
68
|
-
background={background}
|
|
69
|
-
handleTabClick={handleTabClick}
|
|
70
|
-
/>
|
|
71
|
-
) : (
|
|
72
|
-
<div style={{ width: openWidth }}>{children}</div>
|
|
57
|
+
className={cx(
|
|
58
|
+
styles.drawer,
|
|
59
|
+
shadow ? styles.shadow : '',
|
|
60
|
+
fixed ? styles.fixed : styles.inline,
|
|
61
|
+
right ? styles.right : styles.left,
|
|
73
62
|
)}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
styles.toggleButton,
|
|
80
|
-
open && (isStandardButton || (isCustomButton && buttonAnimate))
|
|
81
|
-
? styles.toggleButtonOpen
|
|
82
|
-
: '',
|
|
83
|
-
buttonPosition === 'top' ? styles.top : styles.bottom,
|
|
84
|
-
)}
|
|
63
|
+
style={{ top }}
|
|
64
|
+
>
|
|
65
|
+
<div
|
|
66
|
+
className={cx(styles.drawerContent, border && styles.border)}
|
|
67
|
+
style={{ background, borderColor: border, width: currentWidth }}
|
|
85
68
|
>
|
|
86
|
-
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
69
|
+
{tabs ? (
|
|
70
|
+
<DrawerTabs
|
|
71
|
+
width={openWidth}
|
|
72
|
+
testId={testId}
|
|
73
|
+
open={open}
|
|
74
|
+
tabs={tabs}
|
|
75
|
+
activeTab={activeTab}
|
|
76
|
+
background={background}
|
|
77
|
+
handleTabClick={handleTabClick}
|
|
93
78
|
/>
|
|
79
|
+
) : (
|
|
80
|
+
<div style={{ width: openWidth }}>{children}</div>
|
|
94
81
|
)}
|
|
95
|
-
</
|
|
96
|
-
|
|
97
|
-
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
{button && (
|
|
85
|
+
<span
|
|
86
|
+
className={cx(
|
|
87
|
+
styles.toggleButton,
|
|
88
|
+
open && (isStandardButton || (isCustomButton && buttonAnimate))
|
|
89
|
+
? styles.toggleButtonOpen
|
|
90
|
+
: '',
|
|
91
|
+
buttonPosition === 'top' ? styles.top : styles.bottom,
|
|
92
|
+
)}
|
|
93
|
+
>
|
|
94
|
+
{isCustomButton ? (
|
|
95
|
+
button
|
|
96
|
+
) : (
|
|
97
|
+
<Button
|
|
98
|
+
onClick={setOpen ? () => setOpen(!open) : null}
|
|
99
|
+
round
|
|
100
|
+
icon={right ? <FaChevronRight /> : <FaChevronLeft />}
|
|
101
|
+
/>
|
|
102
|
+
)}
|
|
103
|
+
</span>
|
|
104
|
+
)}
|
|
105
|
+
</div>
|
|
106
|
+
</DrawerResizeWrapper>
|
|
98
107
|
);
|
|
99
108
|
};
|
|
100
109
|
|
|
@@ -115,6 +124,7 @@ Drawer.defaultProps = {
|
|
|
115
124
|
tabs: null,
|
|
116
125
|
defaultTabIndex: 0,
|
|
117
126
|
testId: undefined,
|
|
127
|
+
onResize: null,
|
|
118
128
|
};
|
|
119
129
|
|
|
120
130
|
Drawer.propTypes = {
|
|
@@ -147,4 +157,5 @@ Drawer.propTypes = {
|
|
|
147
157
|
),
|
|
148
158
|
testId: PropTypes.string,
|
|
149
159
|
defaultTabIndex: PropTypes.number,
|
|
160
|
+
onResize: PropTypes.func,
|
|
150
161
|
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
@import '../../style/variables.less';
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
|
+
--color-background-drawer-tabs: var(--color-neutral-100);
|
|
4
5
|
--color-background-drawer-tab: #fff9f4;
|
|
5
6
|
--color-background-drawer-tab-hover: white;
|
|
6
7
|
--color-border-drawer-tab: #e4cbb7;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
html[data-theme='dark'] {
|
|
11
|
+
--color-background-drawer-tabs: var(--color-neutral-900);
|
|
10
12
|
--color-background-drawer-tab: var(--color-primary-muted-800);
|
|
11
13
|
--color-background-drawer-tab-hover: var(--color-primary-muted-700);
|
|
12
14
|
--color-border-drawer-tab: var(--color-border);
|
|
@@ -17,10 +19,12 @@ html[data-theme='dark'] {
|
|
|
17
19
|
|
|
18
20
|
&.left {
|
|
19
21
|
order: -1;
|
|
22
|
+
margin-left: -1px;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
&.right {
|
|
23
26
|
order: 9999;
|
|
27
|
+
margin-right: -1px;
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -58,9 +62,12 @@ html[data-theme='dark'] {
|
|
|
58
62
|
overflow-y: auto;
|
|
59
63
|
max-height: 100%;
|
|
60
64
|
min-height: 100%;
|
|
61
|
-
|
|
62
65
|
transition: width 0.2s;
|
|
63
66
|
|
|
67
|
+
.isResizing & {
|
|
68
|
+
transition: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
@media print {
|
|
65
72
|
background: transparent !important;
|
|
66
73
|
}
|
|
@@ -81,7 +88,7 @@ html[data-theme='dark'] {
|
|
|
81
88
|
display: inline-block;
|
|
82
89
|
transform: rotate(180deg);
|
|
83
90
|
position: absolute;
|
|
84
|
-
z-index:
|
|
91
|
+
z-index: @zindex_drawer + 3;
|
|
85
92
|
|
|
86
93
|
.left & {
|
|
87
94
|
right: -19px;
|
|
@@ -106,28 +113,30 @@ html[data-theme='dark'] {
|
|
|
106
113
|
|
|
107
114
|
.tabs {
|
|
108
115
|
position: absolute;
|
|
109
|
-
top:
|
|
116
|
+
top: 0;
|
|
117
|
+
bottom: 0;
|
|
118
|
+
background-color: var(--color-background-drawer-tabs);
|
|
119
|
+
padding-top: 20px;
|
|
110
120
|
z-index: @zindex_drawer + 1;
|
|
121
|
+
border-left: 1px solid var(--color-border);
|
|
122
|
+
border-right: 1px solid var(--color-border);
|
|
111
123
|
|
|
112
124
|
.left & {
|
|
113
|
-
|
|
114
|
-
margin-left: -1px;
|
|
125
|
+
right: 0;
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
.right & {
|
|
118
|
-
|
|
119
|
-
margin-right: -1px;
|
|
129
|
+
left: 0;
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
.tab {
|
|
123
|
-
height:
|
|
124
|
-
width:
|
|
133
|
+
height: 38px;
|
|
134
|
+
width: 38px;
|
|
125
135
|
display: flex;
|
|
126
136
|
justify-content: center;
|
|
127
137
|
align-items: center;
|
|
128
|
-
margin-bottom: 1px;
|
|
129
|
-
border-radius: 4px;
|
|
130
138
|
cursor: pointer;
|
|
139
|
+
margin: -1px;
|
|
131
140
|
transition: color 0.3s, background-color 0.3s;
|
|
132
141
|
border: 1px solid var(--color-border-drawer-tab);
|
|
133
142
|
|
|
@@ -165,3 +174,37 @@ html[data-theme='dark'] {
|
|
|
165
174
|
}
|
|
166
175
|
}
|
|
167
176
|
}
|
|
177
|
+
|
|
178
|
+
.tabsContent {
|
|
179
|
+
.left & {
|
|
180
|
+
padding-right: 36px;
|
|
181
|
+
}
|
|
182
|
+
.right & {
|
|
183
|
+
padding-left: 36px;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.resizeHandle {
|
|
188
|
+
position: absolute;
|
|
189
|
+
top: 0;
|
|
190
|
+
bottom: 0;
|
|
191
|
+
width: 4px;
|
|
192
|
+
z-index: @zindex_drawer + 2;
|
|
193
|
+
cursor: ew-resize;
|
|
194
|
+
|
|
195
|
+
&:hover {
|
|
196
|
+
background: rgba(@colorPrimary, 0.25);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&:active {
|
|
200
|
+
background: @colorPrimary;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.left & {
|
|
204
|
+
right: 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.right & {
|
|
208
|
+
left: 0;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
FaCogs,
|
|
6
6
|
FaPenAlt,
|
|
7
7
|
FaQuestion,
|
|
8
|
+
FaTrash,
|
|
9
|
+
FaPlus,
|
|
8
10
|
} from 'react-icons/fa';
|
|
9
11
|
import { Drawer, Button, List, Heading, Flex } from '../../..';
|
|
10
12
|
import { listSubheadingsBadges } from '../list/list.stories-data';
|
|
@@ -29,7 +31,7 @@ export default {
|
|
|
29
31
|
},
|
|
30
32
|
decorators: [
|
|
31
33
|
(story) => (
|
|
32
|
-
<Flex height="400px">
|
|
34
|
+
<Flex height="400px" wrap={false}>
|
|
33
35
|
<div
|
|
34
36
|
style={{
|
|
35
37
|
flexGrow: 1,
|
|
@@ -154,3 +156,141 @@ Tabs.parameters = {
|
|
|
154
156
|
},
|
|
155
157
|
},
|
|
156
158
|
};
|
|
159
|
+
|
|
160
|
+
export const MultipleTabbedDrawers = () => {
|
|
161
|
+
const tabs1 = [
|
|
162
|
+
{
|
|
163
|
+
icon: <FaQuestion />,
|
|
164
|
+
content: (
|
|
165
|
+
<div style={{ padding: 20 }}>
|
|
166
|
+
<Heading top>Help</Heading>
|
|
167
|
+
{'Example content goes here lorem ipsum. '.repeat(500)}
|
|
168
|
+
</div>
|
|
169
|
+
),
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
icon: <FaCogs />,
|
|
173
|
+
content: (
|
|
174
|
+
<div style={{ padding: 20 }}>
|
|
175
|
+
<Heading top>Settings</Heading>
|
|
176
|
+
{'Example content goes here lorem ipsum. '.repeat(500)}
|
|
177
|
+
</div>
|
|
178
|
+
),
|
|
179
|
+
},
|
|
180
|
+
];
|
|
181
|
+
const tabs2 = [
|
|
182
|
+
{
|
|
183
|
+
icon: <FaPenAlt />,
|
|
184
|
+
content: (
|
|
185
|
+
<div style={{ padding: 20 }}>
|
|
186
|
+
<Heading top>Edit</Heading>
|
|
187
|
+
{'Example content goes here lorem ipsum. '.repeat(500)}
|
|
188
|
+
</div>
|
|
189
|
+
),
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
return (
|
|
193
|
+
<>
|
|
194
|
+
<Drawer
|
|
195
|
+
right
|
|
196
|
+
background="var(--color-background-raised)"
|
|
197
|
+
tabs={tabs1}
|
|
198
|
+
border
|
|
199
|
+
open
|
|
200
|
+
/>
|
|
201
|
+
<Drawer
|
|
202
|
+
right
|
|
203
|
+
background="var(--color-background-raised)"
|
|
204
|
+
tabs={tabs2}
|
|
205
|
+
border
|
|
206
|
+
open
|
|
207
|
+
/>
|
|
208
|
+
</>
|
|
209
|
+
);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export const Resizable = () => {
|
|
213
|
+
const [open, setOpen] = useState(true);
|
|
214
|
+
const [listDrawerWidth, setListDrawerWidth] = useState(300);
|
|
215
|
+
const [tabbedDrawerWidth, setTabbedDrawerWidth] = useState(300);
|
|
216
|
+
const tabs = [
|
|
217
|
+
{
|
|
218
|
+
icon: <FaQuestion />,
|
|
219
|
+
content: (
|
|
220
|
+
<div style={{ padding: 20 }}>
|
|
221
|
+
<Heading top>Help</Heading>
|
|
222
|
+
{'Example content goes here lorem ipsum. '.repeat(500)}
|
|
223
|
+
</div>
|
|
224
|
+
),
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
return (
|
|
228
|
+
<>
|
|
229
|
+
<Drawer
|
|
230
|
+
button={
|
|
231
|
+
<Button
|
|
232
|
+
onClick={setOpen ? () => setOpen(!open) : null}
|
|
233
|
+
round
|
|
234
|
+
icon={<FaChevronLeft />}
|
|
235
|
+
/>
|
|
236
|
+
}
|
|
237
|
+
open={open}
|
|
238
|
+
background="var(--color-background-raised)"
|
|
239
|
+
border
|
|
240
|
+
width={listDrawerWidth}
|
|
241
|
+
closedWidth={50}
|
|
242
|
+
onResize={(newWidth) => setListDrawerWidth(newWidth)}
|
|
243
|
+
>
|
|
244
|
+
<List
|
|
245
|
+
drawer
|
|
246
|
+
list={{
|
|
247
|
+
name: 'Animals',
|
|
248
|
+
actions: [
|
|
249
|
+
{
|
|
250
|
+
label: 'Add',
|
|
251
|
+
icon: <FaPlus />,
|
|
252
|
+
onClick: () => {},
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
items: [
|
|
256
|
+
{
|
|
257
|
+
id: 1,
|
|
258
|
+
name: 'Aardvark',
|
|
259
|
+
onClick: () => {},
|
|
260
|
+
actions: [
|
|
261
|
+
{
|
|
262
|
+
label: 'Delete',
|
|
263
|
+
icon: <FaTrash />,
|
|
264
|
+
onClick: () => {},
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: 2,
|
|
270
|
+
name: 'Kangaroo',
|
|
271
|
+
active: true,
|
|
272
|
+
actions: [
|
|
273
|
+
{
|
|
274
|
+
label: 'Delete',
|
|
275
|
+
icon: <FaTrash />,
|
|
276
|
+
onClick: () => {},
|
|
277
|
+
},
|
|
278
|
+
],
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
}}
|
|
282
|
+
narrow={!open}
|
|
283
|
+
/>
|
|
284
|
+
</Drawer>
|
|
285
|
+
<Drawer
|
|
286
|
+
right
|
|
287
|
+
background="var(--color-background-raised)"
|
|
288
|
+
tabs={tabs}
|
|
289
|
+
border
|
|
290
|
+
open
|
|
291
|
+
width={tabbedDrawerWidth}
|
|
292
|
+
onResize={(newWidth) => setTabbedDrawerWidth(newWidth)}
|
|
293
|
+
/>
|
|
294
|
+
</>
|
|
295
|
+
);
|
|
296
|
+
};
|
|
@@ -21,14 +21,16 @@ export default {
|
|
|
21
21
|
},
|
|
22
22
|
args: {
|
|
23
23
|
columns: '1fr 1fr 1fr',
|
|
24
|
-
children:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
children: (
|
|
25
|
+
<>
|
|
26
|
+
<Card>Item 1</Card>
|
|
27
|
+
<Card>Item 2</Card>
|
|
28
|
+
<Card>Item 3</Card>
|
|
29
|
+
<Card>Item 4</Card>
|
|
30
|
+
<Card>Item 5</Card>
|
|
31
|
+
<Card>Item 6</Card>
|
|
32
|
+
</>
|
|
33
|
+
),
|
|
32
34
|
},
|
|
33
35
|
};
|
|
34
36
|
|