@qoretechnologies/reqore 0.36.2 → 0.36.4

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 (132) hide show
  1. package/.eslintrc.js +40 -0
  2. package/dist/components/Breadcrumbs/item.d.ts.map +1 -1
  3. package/dist/components/Breadcrumbs/item.js +1 -5
  4. package/dist/components/Breadcrumbs/item.js.map +1 -1
  5. package/dist/components/Comment/index.d.ts.map +1 -1
  6. package/dist/components/Comment/index.js +6 -5
  7. package/dist/components/Comment/index.js.map +1 -1
  8. package/dist/components/ControlGroup/index.d.ts +1 -1
  9. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  10. package/dist/components/ControlGroup/index.js +2 -2
  11. package/dist/components/ControlGroup/index.js.map +1 -1
  12. package/dist/components/Dropdown/index.d.ts +2 -2
  13. package/dist/components/Dropdown/index.d.ts.map +1 -1
  14. package/dist/components/Dropdown/index.js +1 -1
  15. package/dist/components/Dropdown/index.js.map +1 -1
  16. package/dist/components/Dropdown/list.d.ts.map +1 -1
  17. package/dist/components/Dropdown/list.js.map +1 -1
  18. package/dist/components/ExportModal/index.d.ts +2 -2
  19. package/dist/components/ExportModal/index.d.ts.map +1 -1
  20. package/dist/components/Input/index.d.ts.map +1 -1
  21. package/dist/components/Input/index.js +3 -2
  22. package/dist/components/Input/index.js.map +1 -1
  23. package/dist/components/KeyValueTable/index.d.ts +10 -3
  24. package/dist/components/KeyValueTable/index.d.ts.map +1 -1
  25. package/dist/components/KeyValueTable/index.js +9 -5
  26. package/dist/components/KeyValueTable/index.js.map +1 -1
  27. package/dist/components/Menu/index.d.ts.map +1 -1
  28. package/dist/components/Menu/index.js +8 -9
  29. package/dist/components/Menu/index.js.map +1 -1
  30. package/dist/components/Menu/item.d.ts +1 -2
  31. package/dist/components/Menu/item.d.ts.map +1 -1
  32. package/dist/components/Menu/item.js +1 -5
  33. package/dist/components/Menu/item.js.map +1 -1
  34. package/dist/components/Paging/index.d.ts +1 -1
  35. package/dist/components/Paging/index.d.ts.map +1 -1
  36. package/dist/components/Paging/index.js +1 -1
  37. package/dist/components/Paging/index.js.map +1 -1
  38. package/dist/components/Panel/index.d.ts.map +1 -1
  39. package/dist/components/Panel/index.js +2 -1
  40. package/dist/components/Panel/index.js.map +1 -1
  41. package/dist/components/Popover/index.d.ts.map +1 -1
  42. package/dist/components/Popover/index.js +1 -9
  43. package/dist/components/Popover/index.js.map +1 -1
  44. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  45. package/dist/components/RadioGroup/index.js +3 -3
  46. package/dist/components/RadioGroup/index.js.map +1 -1
  47. package/dist/components/Sidebar/index.d.ts +2 -2
  48. package/dist/components/Sidebar/index.d.ts.map +1 -1
  49. package/dist/components/Sidebar/item.d.ts +6 -6
  50. package/dist/components/Sidebar/item.d.ts.map +1 -1
  51. package/dist/components/Sidebar/item.js +3 -9
  52. package/dist/components/Sidebar/item.js.map +1 -1
  53. package/dist/components/Table/body.d.ts +2 -0
  54. package/dist/components/Table/body.d.ts.map +1 -1
  55. package/dist/components/Table/body.js +3 -1
  56. package/dist/components/Table/body.js.map +1 -1
  57. package/dist/components/Table/helpers.js.map +1 -1
  58. package/dist/components/Table/index.d.ts +10 -7
  59. package/dist/components/Table/index.d.ts.map +1 -1
  60. package/dist/components/Table/index.js +15 -3
  61. package/dist/components/Table/index.js.map +1 -1
  62. package/dist/components/Table/row.d.ts +3 -1
  63. package/dist/components/Table/row.d.ts.map +1 -1
  64. package/dist/components/Table/row.js +7 -8
  65. package/dist/components/Table/row.js.map +1 -1
  66. package/dist/components/Tabs/item.d.ts.map +1 -1
  67. package/dist/components/Tabs/item.js +3 -2
  68. package/dist/components/Tabs/item.js.map +1 -1
  69. package/dist/components/TimeAgo/index.js +2 -2
  70. package/dist/components/TimeAgo/index.js.map +1 -1
  71. package/dist/components/Tree/index.d.ts +2 -2
  72. package/dist/components/Tree/index.d.ts.map +1 -1
  73. package/dist/components/Tree/index.js +6 -20
  74. package/dist/components/Tree/index.js.map +1 -1
  75. package/dist/containers/UIProvider.js.map +1 -1
  76. package/dist/helpers/sidebar.d.ts +3 -2
  77. package/dist/helpers/sidebar.d.ts.map +1 -1
  78. package/dist/helpers/sidebar.js +4 -2
  79. package/dist/helpers/sidebar.js.map +1 -1
  80. package/dist/helpers/utils.d.ts +1 -1
  81. package/dist/helpers/utils.d.ts.map +1 -1
  82. package/dist/helpers/utils.js +5 -1
  83. package/dist/helpers/utils.js.map +1 -1
  84. package/dist/hooks/usePopover.d.ts.map +1 -1
  85. package/dist/hooks/usePopover.js +1 -7
  86. package/dist/hooks/usePopover.js.map +1 -1
  87. package/dist/hooks/useTheme.js.map +1 -1
  88. package/dist/hooks/useWhyDidYouUpdate.js +1 -1
  89. package/dist/hooks/useWhyDidYouUpdate.js.map +1 -1
  90. package/package.json +7 -1
  91. package/src/components/Breadcrumbs/item.tsx +0 -1
  92. package/src/components/Comment/index.tsx +6 -4
  93. package/src/components/ControlGroup/index.tsx +1 -3
  94. package/src/components/Dropdown/index.tsx +5 -6
  95. package/src/components/Dropdown/list.tsx +6 -1
  96. package/src/components/ExportModal/index.tsx +1 -1
  97. package/src/components/Input/index.tsx +2 -2
  98. package/src/components/KeyValueTable/index.tsx +21 -5
  99. package/src/components/Menu/index.tsx +1 -2
  100. package/src/components/Menu/item.tsx +1 -7
  101. package/src/components/Paging/index.tsx +0 -1
  102. package/src/components/Panel/index.tsx +3 -2
  103. package/src/components/Popover/index.tsx +0 -5
  104. package/src/components/RadioGroup/index.tsx +2 -1
  105. package/src/components/Sidebar/index.tsx +2 -2
  106. package/src/components/Sidebar/item.tsx +7 -10
  107. package/src/components/Table/body.tsx +7 -1
  108. package/src/components/Table/helpers.ts +1 -1
  109. package/src/components/Table/index.tsx +39 -9
  110. package/src/components/Table/row.tsx +13 -10
  111. package/src/components/Tabs/item.tsx +2 -2
  112. package/src/components/TimeAgo/index.tsx +2 -2
  113. package/src/components/Tree/index.tsx +1 -17
  114. package/src/containers/UIProvider.tsx +1 -1
  115. package/src/helpers/sidebar.ts +20 -36
  116. package/src/helpers/utils.ts +7 -2
  117. package/src/hooks/usePopover.tsx +1 -7
  118. package/src/hooks/useTheme.ts +1 -1
  119. package/src/hooks/useWhyDidYouUpdate.ts +1 -1
  120. package/src/stories/KeyValueTable/KeyValueTable.stories.tsx +46 -0
  121. package/src/stories/Table/Table.stories.tsx +18 -1
  122. package/tests.json +1 -1
  123. package/dist/hooks/useShareForwardedRef.d.ts +0 -3
  124. package/dist/hooks/useShareForwardedRef.d.ts.map +0 -1
  125. package/dist/hooks/useShareForwardedRef.js +0 -25
  126. package/dist/hooks/useShareForwardedRef.js.map +0 -1
  127. package/dist/types/icons____.d.ts +0 -2
  128. package/dist/types/icons____.d.ts.map +0 -1
  129. package/dist/types/icons____.js +0 -5
  130. package/dist/types/icons____.js.map +0 -1
  131. package/src/hooks/useShareForwardedRef.ts +0 -23
  132. package/src/types/icons____.ts +0 -5
@@ -18,8 +18,9 @@ import { useQueryWithDelay } from '../../hooks/useQueryWithDelay';
18
18
  import { IReqoreIntent, IReqoreTooltip } from '../../types/global';
19
19
  import { IReqoreButtonProps, TReqoreBadge } from '../Button';
20
20
  import { IReqoreDropdownItem } from '../Dropdown/list';
21
- import { ReqoreExportModal } from '../ExportModal';
21
+ import { IReqoreExportModalProps, ReqoreExportModal } from '../ExportModal';
22
22
  import ReqoreInput, { IReqoreInputProps } from '../Input';
23
+ import { TReqoreKeyValueTableExportMapper } from '../KeyValueTable';
23
24
  import { IReqorePanelAction, IReqorePanelProps, IReqorePanelSubAction } from '../Panel';
24
25
  import ReqoreTableBody from './body';
25
26
  import ReqoreTableHeader, { IReqoreCustomHeaderCellComponent } from './header';
@@ -43,7 +44,7 @@ import {
43
44
  import { IReqoreTableRowOptions } from './row';
44
45
 
45
46
  export type TReqoreTableColumnContent =
46
- | React.FC<{ [key: string]: any; _selectId?: string | number; _size: TSizes; _dataId: string }>
47
+ | ((data: IReqoreTableRowData) => any)
47
48
  | 'time-ago'
48
49
  | 'tag'
49
50
  | `tag:${TReqoreIntent}`
@@ -51,7 +52,9 @@ export type TReqoreTableColumnContent =
51
52
  | 'title'
52
53
  | `title:${TReqoreIntent}`
53
54
  | 'text'
54
- | `text:${TReqoreIntent}`;
55
+ | `text:${TReqoreIntent}`
56
+ | string
57
+ | number;
55
58
 
56
59
  export interface IReqoreTableColumn extends IReqoreIntent {
57
60
  dataId: string;
@@ -136,6 +139,10 @@ export interface IReqoreTableProps extends IReqorePanelProps {
136
139
  headerCellComponent?: IReqoreCustomHeaderCellComponent;
137
140
  rowComponent?: IReqoreTableRowOptions['rowComponent'];
138
141
  bodyCellComponent?: IReqoreTableRowOptions['cellComponent'];
142
+
143
+ exportMapper?:
144
+ | TReqoreKeyValueTableExportMapper
145
+ | ((data: unknown[]) => IReqoreExportModalProps['data']);
139
146
  }
140
147
 
141
148
  export interface IReqoreTableStyle {
@@ -178,9 +185,29 @@ const StyledTablesWrapper = styled.div`
178
185
  overflow: hidden;
179
186
  `;
180
187
 
188
+ export interface IReqoreTableExportModalProps {
189
+ data: unknown;
190
+ onClose: () => void;
191
+ exportMapper?: IReqoreTableProps['exportMapper'];
192
+ }
193
+
194
+ const ReqoreTableExportModal = ({ data, onClose, exportMapper }) => {
195
+ const fixedData = useMemo(() => {
196
+ let _fixedData = removeInternalData(data);
197
+
198
+ if (exportMapper) {
199
+ _fixedData = exportMapper(_fixedData);
200
+ }
201
+
202
+ return _fixedData;
203
+ }, [data, exportMapper]);
204
+
205
+ return <ReqoreExportModal data={fixedData} onClose={onClose} />;
206
+ };
207
+
181
208
  const ReqoreTable = ({
182
209
  className,
183
- height = 300,
210
+ height,
184
211
  width,
185
212
  columns,
186
213
  data = [],
@@ -210,6 +237,7 @@ const ReqoreTable = ({
210
237
  onSelectClick,
211
238
  paging,
212
239
  exportable,
240
+ exportMapper,
213
241
  ...rest
214
242
  }: IReqoreTableProps) => {
215
243
  const leftTableRef = useRef<HTMLDivElement>(null);
@@ -217,6 +245,7 @@ const ReqoreTable = ({
217
245
  const mainTableRef = useRef<HTMLDivElement>(null);
218
246
  const mainHeaderRef = useRef<HTMLDivElement>(null);
219
247
 
248
+ const [hoveredRow, setHoveredRow] = useState<number>();
220
249
  const [isScrolled, setIsScrolled] = useState<boolean>(false);
221
250
  const [_data, setData] = useState<IReqoreTableData>(data || []);
222
251
  const [_sort, setSort] = useState<IReqoreTableSort | undefined>(fixSort(sort));
@@ -249,7 +278,7 @@ const ReqoreTable = ({
249
278
  }, [_selectedQuant]);
250
279
 
251
280
  const finalColumns = useMemo(() => {
252
- let fullColumns = [..._internalColumns];
281
+ const fullColumns = [..._internalColumns];
253
282
 
254
283
  if (selectable) {
255
284
  fullColumns.unshift({
@@ -669,6 +698,8 @@ const ReqoreTable = ({
669
698
  <ReqoreTableBody
670
699
  ref={refs[type]}
671
700
  refs={refs}
701
+ hoveredRow={hoveredRow}
702
+ setHoveredRow={setHoveredRow}
672
703
  type={type}
673
704
  data={items}
674
705
  columns={tableColumns}
@@ -731,11 +762,10 @@ const ReqoreTable = ({
731
762
  {(pagedData) => (
732
763
  <>
733
764
  {showExportModal && (
734
- <ReqoreExportModal
735
- data={removeInternalData(
736
- showExportModal === 'current' ? pagedData : transformedData
737
- )}
765
+ <ReqoreTableExportModal
766
+ data={showExportModal === 'current' ? pagedData : transformedData}
738
767
  onClose={() => setShowExportModal(undefined)}
768
+ exportMapper={exportMapper}
739
769
  />
740
770
  )}
741
771
  <StyledTablesWrapper className='reqore-table-wrapper'>
@@ -1,6 +1,6 @@
1
1
  /* @flow */
2
2
  import { isFunction, isString } from 'lodash';
3
- import React, { ReactElement, useState } from 'react';
3
+ import React, { ReactElement } from 'react';
4
4
  import styled, { css } from 'styled-components';
5
5
  import { IReqoreTableColumn, IReqoreTableData, IReqoreTableRowClick } from '.';
6
6
  import { ReqoreButton, ReqoreControlGroup } from '../..';
@@ -28,6 +28,8 @@ export interface IReqoreTableRowOptions {
28
28
  flat?: boolean;
29
29
  cellComponent?: IReqoreCustomTableBodyCell;
30
30
  rowComponent?: IReqoreCustomTableRow;
31
+ setHoveredRow?: (index: number) => void;
32
+ hoveredRow?: number;
31
33
  }
32
34
  export interface IReqoreCustomTableRowProps extends IReqoreTableRowOptions {
33
35
  style?: React.CSSProperties;
@@ -90,11 +92,12 @@ const ReqoreTableRow = ({
90
92
  flat,
91
93
  cellComponent,
92
94
  rowComponent,
95
+ setHoveredRow,
96
+ hoveredRow,
93
97
  },
94
98
  style,
95
99
  index,
96
100
  }: IReqoreTableRowProps) => {
97
- const [isHovered, setIsHovered] = useState<boolean>(false);
98
101
  const isSelected =
99
102
  data[index]._selectId &&
100
103
  selected.find((selectId) => selectId.toString() === data[index]._selectId.toString());
@@ -145,12 +148,12 @@ const ReqoreTableRow = ({
145
148
 
146
149
  if (isString(content)) {
147
150
  // Separate the content string by colon
148
- let [type, intentOrColor] = content.split(':');
151
+ const [type, intentOrColor] = content.split(':');
149
152
  // Check if the intent starts with hash for tags
150
- let intent: TReqoreIntent = intentOrColor?.startsWith('#')
153
+ const intent: TReqoreIntent = intentOrColor?.startsWith('#')
151
154
  ? undefined
152
155
  : (intentOrColor as TReqoreIntent);
153
- let color: TReqoreHexColor =
156
+ const color: TReqoreHexColor =
154
157
  intentOrColor?.startsWith('#') && type === 'tag'
155
158
  ? (intentOrColor as TReqoreHexColor)
156
159
  : undefined;
@@ -176,7 +179,7 @@ const ReqoreTableRow = ({
176
179
  </ReqoreP>
177
180
  );
178
181
  default:
179
- return <ReqoreP className='reqore-table-text'>{data[dataId]}</ReqoreP>;
182
+ return <ReqoreP className='reqore-table-text'>{content}</ReqoreP>;
180
183
  }
181
184
  }
182
185
 
@@ -218,7 +221,7 @@ const ReqoreTableRow = ({
218
221
  flat,
219
222
  even: index % 2 === 0 ? true : false,
220
223
  intent: cell?.intent || data[index]._intent || intent,
221
- hovered: isHovered,
224
+ hovered: hoveredRow === index,
222
225
  interactive: !!cell?.onClick || !!onRowClick,
223
226
  interactiveCell: !!cell?.onClick,
224
227
  onClick: (e: React.MouseEvent<HTMLDivElement>) => {
@@ -246,15 +249,15 @@ const ReqoreTableRow = ({
246
249
  <RowComponent
247
250
  style={style}
248
251
  className='reqore-table-row'
249
- interactive={!!onRowClick}
252
+ interactive={!!onRowClick && !data[index]._disabled}
250
253
  onMouseEnter={() => {
251
254
  // Set hovered is this row is interactive
252
255
  if (onRowClick || (selectable && data[index]._selectId && !data[index]._disabled)) {
253
- setIsHovered(true);
256
+ setHoveredRow(index);
254
257
  }
255
258
  }}
256
259
  onMouseLeave={() => {
257
- setIsHovered(false);
260
+ setHoveredRow(undefined);
258
261
  }}
259
262
  >
260
263
  {renderCells(columns, data)}
@@ -1,3 +1,4 @@
1
+ import { omit } from 'lodash';
1
2
  import { forwardRef, memo } from 'react';
2
3
  import styled, { css } from 'styled-components';
3
4
  import { IReqoreTabsListItem } from '.';
@@ -129,7 +130,6 @@ const ReqoreTabsListItem = memo(
129
130
  className,
130
131
  flat = true,
131
132
  wrapTabNames,
132
- id,
133
133
  padded,
134
134
  ...rest
135
135
  }: IReqoreTabListItemProps,
@@ -168,7 +168,7 @@ const ReqoreTabsListItem = memo(
168
168
  tooltip={tooltip}
169
169
  customTheme={theme}
170
170
  className={`reqore-tabs-list-item ${active ? 'reqore-tabs-list-item-active' : ''}`}
171
- {...rest}
171
+ {...omit(rest, ['id'])}
172
172
  >
173
173
  {label}
174
174
  </ReqoreButton>
@@ -4,11 +4,11 @@ import { useInterval } from 'react-use';
4
4
  import { getTimeAgoIntervalDelay } from '../../helpers/time';
5
5
 
6
6
  export const TimeAgo = ({ time }: { time: number | string }) => {
7
- const [_lastUpdate, _setLastUpdate] = useState<number>(Date.now());
7
+ const setUpdate = useState<number>(Date.now());
8
8
  const _time = typeof time === 'number' ? time : Date.parse(time);
9
9
 
10
10
  useInterval(() => {
11
- _setLastUpdate(Date.now());
11
+ setUpdate[1](Date.now());
12
12
  }, getTimeAgoIntervalDelay(_time));
13
13
 
14
14
  return timeago(_time);
@@ -13,7 +13,7 @@ import { getExportActions, getZoomActions, sizeToZoom, zoomToSize } from '../Tab
13
13
  import ReqoreTag from '../Tag';
14
14
 
15
15
  export interface IReqoreTreeProps extends IReqorePanelProps, IWithReqoreSize {
16
- data: Object | Array<any>;
16
+ data: Record<string, unknown> | Array<any>;
17
17
  mode?: 'tree' | 'copy';
18
18
  expanded?: boolean;
19
19
  showTypes?: boolean;
@@ -36,7 +36,6 @@ export const StyledTreeLabel = styled(ReqoreMessage)`
36
36
 
37
37
  export const ReqoreTree = ({
38
38
  data,
39
- mode = 'tree',
40
39
  size = 'normal',
41
40
  expanded,
42
41
  showTypes,
@@ -154,21 +153,6 @@ export const ReqoreTree = ({
154
153
  });
155
154
  };
156
155
 
157
- const renderText = (data, tabs = '') => {
158
- let text = '';
159
-
160
- Object.keys(data).forEach((key) => {
161
- if (typeof data[key] !== 'object' || !data[key]) {
162
- text += `${tabs}${key}: ${data[key]}\r\n`;
163
- } else {
164
- text += `${tabs}${key}:\r\n`;
165
- text += renderText(data[key], `${tabs}\t`);
166
- }
167
- });
168
-
169
- return text;
170
- };
171
-
172
156
  const actions = useMemo(() => {
173
157
  let _actions: IReqorePanelAction[] = [];
174
158
 
@@ -66,7 +66,7 @@ const StyledPortal = styled.div`
66
66
  `}
67
67
  `;
68
68
 
69
- const ReqorePortal = forwardRef<HTMLDivElement, {}>((_props, ref) => {
69
+ const ReqorePortal = forwardRef<HTMLDivElement, object>((_props, ref) => {
70
70
  return (
71
71
  <ReqoreThemeProvider>
72
72
  <StyledPortal id='reqore-portal' ref={ref} />
@@ -1,47 +1,42 @@
1
- import { reduce, size } from "lodash";
2
- import {
3
- IQorusSidebarCustomItem,
4
- IQorusSidebarItems,
5
- } from "../components/Sidebar";
1
+ import { reduce, size } from 'lodash';
2
+ import { IQorusSidebarCustomItem, IQorusSidebarItems } from '../components/Sidebar';
6
3
 
7
- export const transformMenu: Function = (
4
+ export const transformMenu = (
8
5
  menu: IQorusSidebarItems,
9
6
  bookmarks: string[],
10
7
  customItems?: IQorusSidebarCustomItem[]
11
- ): Object => {
8
+ ) => {
12
9
  let newMenu: IQorusSidebarItems = { ...menu };
13
10
  let _qorusCustomElements;
14
11
  let _qorusBookmarks;
15
12
 
16
13
  if (size(bookmarks)) {
17
14
  _qorusBookmarks = {
18
- title: "Bookmarks",
15
+ title: 'Bookmarks',
19
16
  items: [],
20
17
  };
21
18
 
22
19
  newMenu = reduce(
23
20
  newMenu,
24
21
  (cur, menuSection, name: string) => {
25
- let newSection = { ...menuSection };
22
+ const newSection = { ...menuSection };
26
23
 
27
24
  newSection.items = [...newSection.items]
28
25
  .map((newSectionItem) => {
29
26
  const copySectionItem = { ...newSectionItem };
30
27
 
31
28
  if (copySectionItem.submenu) {
32
- copySectionItem.submenu = copySectionItem.submenu.filter(
33
- (submenuItem) => {
34
- const isItemInSubmenu = bookmarks.find(
35
- (favoriteItem) => favoriteItem === submenuItem.id
36
- );
29
+ copySectionItem.submenu = copySectionItem.submenu.filter((submenuItem) => {
30
+ const isItemInSubmenu = bookmarks.find(
31
+ (favoriteItem) => favoriteItem === submenuItem.id
32
+ );
37
33
 
38
- if (isItemInSubmenu) {
39
- _qorusBookmarks.items.push(submenuItem);
40
- }
41
-
42
- return !isItemInSubmenu;
34
+ if (isItemInSubmenu) {
35
+ _qorusBookmarks.items.push(submenuItem);
43
36
  }
44
- );
37
+
38
+ return !isItemInSubmenu;
39
+ });
45
40
 
46
41
  if (size(copySectionItem.submenu)) {
47
42
  return copySectionItem;
@@ -49,11 +44,7 @@ export const transformMenu: Function = (
49
44
  return undefined;
50
45
  }
51
46
  } else {
52
- if (
53
- !bookmarks.find(
54
- (favoriteItem) => favoriteItem === copySectionItem.id
55
- )
56
- ) {
47
+ if (!bookmarks.find((favoriteItem) => favoriteItem === copySectionItem.id)) {
57
48
  return copySectionItem;
58
49
  } else {
59
50
  _qorusBookmarks.items.push(copySectionItem);
@@ -82,17 +73,10 @@ export const transformMenu: Function = (
82
73
  return newMenu;
83
74
  };
84
75
 
85
- export const isActive = (
86
- to: string,
87
- currentPath: string,
88
- exact?: boolean
89
- ): boolean => (exact ? currentPath === to : currentPath.startsWith(to));
90
-
91
- export const isActiveMulti: Function = (
92
- to: string[],
93
- currentPath: string,
94
- exact?: boolean
95
- ): boolean => {
76
+ export const isActive = (to: string, currentPath: string, exact?: boolean): boolean =>
77
+ exact ? currentPath === to : currentPath.startsWith(to);
78
+
79
+ export const isActiveMulti = (to: string[], currentPath: string, exact?: boolean): boolean => {
96
80
  let active: boolean = false;
97
81
 
98
82
  to.forEach((path: string) => {
@@ -13,7 +13,7 @@ import { NUMBER_TO_SIZE, SIZES, SIZE_TO_NUMBER, TSizes } from '../constants/size
13
13
 
14
14
  export const sleep = async (ms: number) => await new Promise((r) => setTimeout(r, ms));
15
15
 
16
- export const getTypeFromValue: Function = (item: any): string => {
16
+ export const getTypeFromValue = (item: any): string => {
17
17
  if (isBoolean(item)) {
18
18
  return 'boolean';
19
19
  }
@@ -57,7 +57,12 @@ export const getLineCount = (value: string | null): number => {
57
57
  // to a CSV string
58
58
  export const convertToCSV = (objArray: any[]): string => {
59
59
  const header = Object.keys(objArray[0]).join(',');
60
- const rows = objArray.map((obj) => Object.values(obj).join(','));
60
+ const rows = objArray.map((obj) =>
61
+ Object.values(obj)
62
+ .map((value) => JSON.stringify(value))
63
+ .join(',')
64
+ );
65
+
61
66
  return [header, ...rows].join('\n');
62
67
  };
63
68
 
@@ -194,13 +194,7 @@ const usePopover = ({
194
194
  }
195
195
  }
196
196
  };
197
- }, [
198
- targetElement?.toString(),
199
- //@ts-ignore
200
- content,
201
- current,
202
- currentPopover,
203
- ]);
197
+ }, [targetElement?.toString(), content, current, currentPopover]);
204
198
 
205
199
  useUnmount(() => {
206
200
  cancelTimeout();
@@ -27,7 +27,7 @@ export const useReqoreTheme = (
27
27
  return theme;
28
28
  }
29
29
 
30
- let _customTheme: IReqoreCustomTheme = cloneDeep(customTheme);
30
+ const _customTheme: IReqoreCustomTheme = cloneDeep(customTheme);
31
31
 
32
32
  if (_customTheme.main) {
33
33
  _customTheme.main = getColorFromMaybeString(theme, customTheme.main);
@@ -23,7 +23,7 @@ export function useWhyDidYouUpdate(name, props) {
23
23
  });
24
24
  // If changesObj not empty then output to console
25
25
  if (Object.keys(changesObj).length) {
26
- console.log('[why-did-you-update]', name, changesObj);
26
+ console.warn('[why-did-you-update]', name, changesObj);
27
27
  }
28
28
  }
29
29
  // Finally update previousProps with current props for next hook call
@@ -1,4 +1,6 @@
1
1
  import { StoryObj } from '@storybook/react';
2
+ import { fireEvent, userEvent, waitFor, within } from '@storybook/testing-library';
3
+ import { noop } from 'lodash';
2
4
  import ReqoreIcon from '../../components/Icon';
3
5
  import { IReqoreKeyValueTableProps, ReqoreKeyValueTable } from '../../components/KeyValueTable';
4
6
  import { IReqoreTableRowData, TReqoreTableColumnContent } from '../../components/Table';
@@ -92,6 +94,16 @@ export const Basic: Story = {};
92
94
  export const NoLabel: Story = {
93
95
  args: {
94
96
  label: undefined,
97
+ onRowClick: noop,
98
+ },
99
+ };
100
+
101
+ export const InteractiveRows: Story = {
102
+ args: {
103
+ onRowClick: noop,
104
+ },
105
+ play: async ({ canvasElement }) => {
106
+ await userEvent.hover(canvasElement.querySelectorAll('.reqore-table-row')[2]);
95
107
  },
96
108
  };
97
109
 
@@ -107,6 +119,12 @@ export const NotFlat: Story = {
107
119
  },
108
120
  };
109
121
 
122
+ export const NoHeight: Story = {
123
+ args: {
124
+ height: undefined,
125
+ },
126
+ };
127
+
110
128
  export const Striped: Story = {
111
129
  args: {
112
130
  striped: true,
@@ -245,6 +263,12 @@ export const CustomPaging: Story = {
245
263
  },
246
264
  };
247
265
 
266
+ export const CustomKeyRenderer: Story = {
267
+ args: {
268
+ keyRenderer: (label) => `${label}_custom`,
269
+ },
270
+ };
271
+
248
272
  export const CustomValueRenderer: Story = {
249
273
  args: {
250
274
  valueRenderer: ({ value, tableKey }, Component): TReqoreTableColumnContent | JSX.Element => {
@@ -263,3 +287,25 @@ export const CustomValueRenderer: Story = {
263
287
  },
264
288
  },
265
289
  };
290
+
291
+ export const CustomExportMapper: Story = {
292
+ args: {
293
+ exportable: true,
294
+ exportMapper: (data) => {
295
+ return data.reduce(
296
+ (acc, row) => ({
297
+ ...acc,
298
+ [row.tableKey.toString()]: row.value,
299
+ }),
300
+ {}
301
+ );
302
+ },
303
+ },
304
+ play: async ({ canvasElement, ...rest }) => {
305
+ const canvas = within(canvasElement);
306
+ // @ts-expect-error
307
+ await ExportableTable.play({ canvasElement, ...rest });
308
+ await fireEvent.click(canvas.getAllByText('Export full data')[0]);
309
+ await waitFor(() => canvas.findAllByText('Export data'), { timeout: 5000 });
310
+ },
311
+ };
@@ -1,5 +1,6 @@
1
1
  import { StoryObj } from '@storybook/react';
2
- import { fireEvent, waitFor, within } from '@storybook/testing-library';
2
+ import { fireEvent, userEvent, waitFor, within } from '@storybook/testing-library';
3
+ import { noop, slice } from 'lodash';
3
4
  import { StyledEffect } from '../../components/Effect';
4
5
  import { IReqoreTableColumn, IReqoreTableProps, IReqoreTableRowData } from '../../components/Table';
5
6
  import { IReqoreCustomTableBodyCellProps } from '../../components/Table/cell';
@@ -375,6 +376,22 @@ export const NotFlat: Story = {
375
376
  },
376
377
  };
377
378
 
379
+ export const NoHeight: Story = {
380
+ args: {
381
+ height: undefined,
382
+ data: slice(tableData.data, 0, 150),
383
+ },
384
+ };
385
+
386
+ export const InteractiveRows: Story = {
387
+ args: {
388
+ onRowClick: noop,
389
+ },
390
+ play: async ({ canvasElement }) => {
391
+ await userEvent.hover(canvasElement.querySelectorAll('.reqore-table-row')[2]);
392
+ },
393
+ };
394
+
378
395
  export const Striped: Story = {
379
396
  args: {
380
397
  striped: true,