@qoretechnologies/reqore 0.36.6 → 0.36.7
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/dist/components/Panel/index.d.ts +1 -0
- package/dist/components/Panel/index.d.ts.map +1 -1
- package/dist/components/Panel/index.js +10 -9
- package/dist/components/Panel/index.js.map +1 -1
- package/dist/components/Table/body.d.ts +2 -2
- package/dist/components/Table/body.d.ts.map +1 -1
- package/dist/components/Table/body.js +1 -1
- package/dist/components/Table/body.js.map +1 -1
- package/dist/components/Table/cell.d.ts +1 -1
- package/dist/components/Table/cell.d.ts.map +1 -1
- package/dist/components/Table/cell.js +2 -2
- package/dist/components/Table/cell.js.map +1 -1
- package/dist/components/Table/header.d.ts +2 -2
- package/dist/components/Table/header.d.ts.map +1 -1
- package/dist/components/Table/header.js +1 -1
- package/dist/components/Table/header.js.map +1 -1
- package/dist/components/Table/row.d.ts +1 -1
- package/dist/components/Table/row.d.ts.map +1 -1
- package/dist/components/Table/row.js +3 -3
- package/dist/components/Table/row.js.map +1 -1
- package/dist/components/Table/value.d.ts +2 -1
- package/dist/components/Table/value.d.ts.map +1 -1
- package/dist/components/Table/value.js +3 -3
- package/dist/components/Table/value.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Panel/index.tsx +10 -5
- package/src/components/Table/body.tsx +2 -2
- package/src/components/Table/cell.tsx +9 -7
- package/src/components/Table/header.tsx +2 -2
- package/src/components/Table/row.tsx +193 -173
- package/src/components/Table/value.tsx +3 -2
- package/src/stories/Panel/Panel.stories.tsx +26 -0
- package/tests.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
import { isFunction, isString } from 'lodash';
|
|
3
|
-
import React, { ReactElement } from 'react';
|
|
3
|
+
import React, { ReactElement, memo } from 'react';
|
|
4
4
|
import styled, { css } from 'styled-components';
|
|
5
5
|
import { IReqoreTableColumn, IReqoreTableData, IReqoreTableRowClick } from '.';
|
|
6
6
|
import { ReqoreButton, ReqoreControlGroup } from '../..';
|
|
@@ -78,191 +78,211 @@ export interface IReqoreTableCellStyle {
|
|
|
78
78
|
padded?: IReqoreTableColumn['cell']['padded'];
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
const ReqoreTableRow = (
|
|
82
|
-
|
|
83
|
-
data
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
81
|
+
const ReqoreTableRow = memo(
|
|
82
|
+
({
|
|
83
|
+
data: {
|
|
84
|
+
data,
|
|
85
|
+
columns,
|
|
86
|
+
selectable,
|
|
87
|
+
onSelectClick,
|
|
88
|
+
selected,
|
|
89
|
+
onRowClick,
|
|
90
|
+
striped,
|
|
91
|
+
size,
|
|
92
|
+
selectedRowIntent,
|
|
93
|
+
flat,
|
|
94
|
+
cellComponent,
|
|
95
|
+
rowComponent,
|
|
96
|
+
setHoveredRow,
|
|
97
|
+
hoveredRow,
|
|
98
|
+
},
|
|
99
|
+
style,
|
|
100
|
+
index,
|
|
101
|
+
}: IReqoreTableRowProps) => {
|
|
102
|
+
const isSelected =
|
|
103
|
+
data[index]._selectId &&
|
|
104
|
+
selected.find((selectId) => selectId.toString() === data[index]._selectId.toString());
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
const CellComponent = cellComponent || ReqoreTableBodyCell;
|
|
107
|
+
const RowComponent = rowComponent || StyledTableRow;
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
let content = cell?.content;
|
|
109
|
+
const renderContent = (
|
|
110
|
+
cell: IReqoreTableColumn['cell'],
|
|
111
|
+
data: any,
|
|
112
|
+
dataId: string,
|
|
113
|
+
align?: 'center' | 'left' | 'right'
|
|
114
|
+
): ReactElement<any, any> => {
|
|
115
|
+
if (cell?.actions) {
|
|
116
|
+
return (
|
|
117
|
+
<ReqoreControlGroup
|
|
118
|
+
size={size}
|
|
119
|
+
stack
|
|
120
|
+
fill
|
|
121
|
+
fluid
|
|
122
|
+
style={{ height: '100%' }}
|
|
123
|
+
rounded={false}
|
|
124
|
+
>
|
|
125
|
+
{cell.actions(data).map((action, index) => (
|
|
126
|
+
<ReqoreButton
|
|
127
|
+
key={index}
|
|
128
|
+
rounded={false}
|
|
129
|
+
iconsAlign={align === 'center' ? 'center' : 'sides'}
|
|
130
|
+
textAlign={align}
|
|
131
|
+
{...action}
|
|
132
|
+
onClick={(e) => {
|
|
133
|
+
e.stopPropagation();
|
|
136
134
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
action.onClick?.(e);
|
|
136
|
+
}}
|
|
137
|
+
/>
|
|
138
|
+
))}
|
|
139
|
+
</ReqoreControlGroup>
|
|
140
|
+
);
|
|
143
141
|
}
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
content = content(data) as any;
|
|
147
|
-
}
|
|
143
|
+
let content = cell?.content;
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const color: TReqoreHexColor =
|
|
157
|
-
intentOrColor?.startsWith('#') && type === 'tag'
|
|
158
|
-
? (intentOrColor as TReqoreHexColor)
|
|
159
|
-
: undefined;
|
|
160
|
-
// Render content based on the type
|
|
161
|
-
switch (type) {
|
|
162
|
-
case 'time-ago':
|
|
163
|
-
return <TimeAgo time={data[dataId]} />;
|
|
164
|
-
case 'tag':
|
|
165
|
-
return (
|
|
166
|
-
<ReqoreTag
|
|
167
|
-
label={data[dataId]}
|
|
168
|
-
size={size}
|
|
169
|
-
intent={intent as TReqoreIntent}
|
|
170
|
-
color={color}
|
|
171
|
-
/>
|
|
172
|
-
);
|
|
173
|
-
case 'title':
|
|
174
|
-
return <ReqoreH4 intent={intent as TReqoreIntent}>{data[dataId]}</ReqoreH4>;
|
|
175
|
-
case 'text':
|
|
176
|
-
return (
|
|
177
|
-
<ReqoreP className='reqore-table-text' intent={intent as TReqoreIntent}>
|
|
178
|
-
{data[dataId]}
|
|
179
|
-
</ReqoreP>
|
|
180
|
-
);
|
|
181
|
-
default:
|
|
182
|
-
return <ReqoreP className='reqore-table-text'>{content}</ReqoreP>;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
145
|
+
if (isFunction(content)) {
|
|
146
|
+
// Check what type does the content function return
|
|
147
|
+
if (React.isValidElement(content(data))) {
|
|
148
|
+
const Content = content;
|
|
149
|
+
// If it's a react element, return it
|
|
150
|
+
return <Content {...data} _size={size} _dataId={dataId} />;
|
|
151
|
+
}
|
|
185
152
|
|
|
186
|
-
|
|
187
|
-
|
|
153
|
+
// If it's a function, call it and return the result
|
|
154
|
+
content = content(data) as any;
|
|
155
|
+
}
|
|
188
156
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if
|
|
193
|
-
|
|
157
|
+
if (isString(content)) {
|
|
158
|
+
// Separate the content string by colon
|
|
159
|
+
const [type, intentOrColor] = content.split(':');
|
|
160
|
+
// Check if the intent starts with hash for tags
|
|
161
|
+
const intent: TReqoreIntent = intentOrColor?.startsWith('#')
|
|
162
|
+
? undefined
|
|
163
|
+
: (intentOrColor as TReqoreIntent);
|
|
164
|
+
const color: TReqoreHexColor =
|
|
165
|
+
intentOrColor?.startsWith('#') && type === 'tag'
|
|
166
|
+
? (intentOrColor as TReqoreHexColor)
|
|
167
|
+
: undefined;
|
|
168
|
+
// Render content based on the type
|
|
169
|
+
switch (type) {
|
|
170
|
+
case 'time-ago':
|
|
171
|
+
return <TimeAgo time={data[dataId]} />;
|
|
172
|
+
case 'tag':
|
|
173
|
+
return (
|
|
174
|
+
<ReqoreTag
|
|
175
|
+
label={data[dataId]}
|
|
176
|
+
size={size}
|
|
177
|
+
intent={intent as TReqoreIntent}
|
|
178
|
+
color={color}
|
|
179
|
+
/>
|
|
180
|
+
);
|
|
181
|
+
case 'title':
|
|
182
|
+
return <ReqoreH4 intent={intent as TReqoreIntent}>{data[dataId]}</ReqoreH4>;
|
|
183
|
+
case 'text':
|
|
184
|
+
return (
|
|
185
|
+
<ReqoreP className='reqore-table-text' intent={intent as TReqoreIntent}>
|
|
186
|
+
{data[dataId]}
|
|
187
|
+
</ReqoreP>
|
|
188
|
+
);
|
|
189
|
+
default:
|
|
190
|
+
return <ReqoreP className='reqore-table-text'>{content}</ReqoreP>;
|
|
194
191
|
}
|
|
192
|
+
}
|
|
195
193
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
? typeof cell?.tooltip(data[index][dataId]) !== 'object'
|
|
199
|
-
? {
|
|
200
|
-
content: cell.tooltip(data[index][dataId]) as string,
|
|
201
|
-
}
|
|
202
|
-
: (cell.tooltip(data[index][dataId]) as IReqoreTooltip)
|
|
203
|
-
: {};
|
|
194
|
+
return <ReqoreP className='reqore-table-text'>{data[dataId]}</ReqoreP>;
|
|
195
|
+
};
|
|
204
196
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (cell?.onClick) {
|
|
229
|
-
e.stopPropagation();
|
|
230
|
-
cell.onClick(data[index]);
|
|
231
|
-
} else if (onRowClick) {
|
|
232
|
-
e.stopPropagation();
|
|
233
|
-
onRowClick(data[index]);
|
|
234
|
-
} else if (selectable && data[index]._selectId) {
|
|
235
|
-
// Otherwise select the row if selectable
|
|
236
|
-
onSelectClick(data[index]._selectId!);
|
|
197
|
+
const renderCells = (columns: IReqoreTableColumn[], data: IReqoreTableData) =>
|
|
198
|
+
getOnlyShownColumns(columns).map(
|
|
199
|
+
({
|
|
200
|
+
width,
|
|
201
|
+
minWidth,
|
|
202
|
+
maxWidth,
|
|
203
|
+
resizedWidth,
|
|
204
|
+
grow,
|
|
205
|
+
dataId,
|
|
206
|
+
cell,
|
|
207
|
+
header,
|
|
208
|
+
align,
|
|
209
|
+
intent,
|
|
210
|
+
}) => {
|
|
211
|
+
if (header?.columns) {
|
|
212
|
+
return renderCells(header.columns, data);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Build the tooltip
|
|
216
|
+
const tooltip: IReqoreTooltip = cell?.tooltip
|
|
217
|
+
? typeof cell?.tooltip(data[index][dataId]) !== 'object'
|
|
218
|
+
? {
|
|
219
|
+
content: cell.tooltip(data[index][dataId]) as string,
|
|
237
220
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
} as IReqoreTableCellStyle)}
|
|
241
|
-
>
|
|
242
|
-
{renderContent(cell, data[index], dataId, align)}
|
|
243
|
-
</CellComponent>
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
);
|
|
221
|
+
: (cell.tooltip(data[index][dataId]) as IReqoreTooltip)
|
|
222
|
+
: {};
|
|
247
223
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
224
|
+
return (
|
|
225
|
+
<CellComponent
|
|
226
|
+
key={dataId}
|
|
227
|
+
{...({
|
|
228
|
+
width: resizedWidth || width,
|
|
229
|
+
minWidth,
|
|
230
|
+
maxWidth,
|
|
231
|
+
grow,
|
|
232
|
+
align,
|
|
233
|
+
size,
|
|
234
|
+
striped,
|
|
235
|
+
tooltip,
|
|
236
|
+
padded: cell?.padded,
|
|
237
|
+
disabled: data[index]._disabled,
|
|
238
|
+
selected: !!isSelected,
|
|
239
|
+
selectedIntent: selectedRowIntent,
|
|
240
|
+
flat,
|
|
241
|
+
even: index % 2 === 0 ? true : false,
|
|
242
|
+
intent: cell?.intent || data[index]._intent || intent,
|
|
243
|
+
hovered: hoveredRow === index,
|
|
244
|
+
interactive: !!cell?.onClick || !!onRowClick,
|
|
245
|
+
interactiveCell: !!cell?.onClick,
|
|
246
|
+
onClick: (e: React.MouseEvent<HTMLDivElement>) => {
|
|
247
|
+
if (cell?.onClick) {
|
|
248
|
+
e.stopPropagation();
|
|
249
|
+
cell.onClick(data[index]);
|
|
250
|
+
} else if (onRowClick) {
|
|
251
|
+
e.stopPropagation();
|
|
252
|
+
onRowClick(data[index]);
|
|
253
|
+
} else if (selectable && data[index]._selectId) {
|
|
254
|
+
// Otherwise select the row if selectable
|
|
255
|
+
onSelectClick(data[index]._selectId!);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
className: 'reqore-table-cell',
|
|
259
|
+
} as IReqoreTableCellStyle)}
|
|
260
|
+
>
|
|
261
|
+
{renderContent(cell, data[index], dataId, align)}
|
|
262
|
+
</CellComponent>
|
|
263
|
+
);
|
|
257
264
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
return (
|
|
268
|
+
<RowComponent
|
|
269
|
+
style={style}
|
|
270
|
+
className='reqore-table-row'
|
|
271
|
+
interactive={!!onRowClick && !data[index]._disabled}
|
|
272
|
+
onMouseEnter={() => {
|
|
273
|
+
// Set hovered is this row is interactive
|
|
274
|
+
if (onRowClick || (selectable && data[index]._selectId && !data[index]._disabled)) {
|
|
275
|
+
setHoveredRow(index);
|
|
276
|
+
}
|
|
277
|
+
}}
|
|
278
|
+
onMouseLeave={() => {
|
|
279
|
+
setHoveredRow(undefined);
|
|
280
|
+
}}
|
|
281
|
+
>
|
|
282
|
+
{renderCells(columns, data)}
|
|
283
|
+
</RowComponent>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
);
|
|
267
287
|
|
|
268
288
|
export default ReqoreTableRow;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
1
2
|
import ReqoreIcon from '../Icon';
|
|
2
3
|
import { ReqoreP } from '../Paragraph';
|
|
3
4
|
|
|
@@ -5,7 +6,7 @@ export interface IReqoreTableValueProps {
|
|
|
5
6
|
value?: string | number | boolean | any[] | { [key: string]: any };
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
export const ReqoreTableValue = ({ value }: IReqoreTableValueProps) => {
|
|
9
|
+
export const ReqoreTableValue = memo(({ value }: IReqoreTableValueProps) => {
|
|
9
10
|
if (value === undefined || value === null) {
|
|
10
11
|
return <>-</>;
|
|
11
12
|
}
|
|
@@ -24,4 +25,4 @@ export const ReqoreTableValue = ({ value }: IReqoreTableValueProps) => {
|
|
|
24
25
|
default:
|
|
25
26
|
return <ReqoreP className='reqore-table-text'>{JSON.stringify(value)}</ReqoreP>;
|
|
26
27
|
}
|
|
27
|
-
};
|
|
28
|
+
});
|
|
@@ -445,6 +445,32 @@ export const ActionsShownOnHover: Story = {
|
|
|
445
445
|
},
|
|
446
446
|
};
|
|
447
447
|
|
|
448
|
+
export const ActionsShownOnlyWhenExpanded: Story = {
|
|
449
|
+
render: (args) => (
|
|
450
|
+
<ReqoreControlGroup verticalAlign='flex-start'>
|
|
451
|
+
<ReqorePanel {...args} isCollapsed fluid />
|
|
452
|
+
<ReqorePanel {...args} fluid />
|
|
453
|
+
</ReqoreControlGroup>
|
|
454
|
+
),
|
|
455
|
+
|
|
456
|
+
args: {
|
|
457
|
+
collapsible: true,
|
|
458
|
+
showActionsWhenCollapsed: false,
|
|
459
|
+
actions: [{ label: 'test' }],
|
|
460
|
+
children: 'This is a panel',
|
|
461
|
+
bottomActions: [
|
|
462
|
+
{
|
|
463
|
+
position: 'right',
|
|
464
|
+
fluid: false,
|
|
465
|
+
group: [
|
|
466
|
+
{ label: 'test 2', show: true },
|
|
467
|
+
{ label: 'test 3', show: true },
|
|
468
|
+
],
|
|
469
|
+
},
|
|
470
|
+
],
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
|
|
448
474
|
export const TransparentFlat: Story = {
|
|
449
475
|
render: Template,
|
|
450
476
|
|