@qoretechnologies/reqore 0.36.0 → 0.36.2

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 (211) hide show
  1. package/__tests__/collection.test.tsx +1 -22
  2. package/__tests__/table.test.tsx +1 -1
  3. package/__tests__/tree.test.tsx +0 -18
  4. package/dist/components/Breadcrumbs/index.js +1 -1
  5. package/dist/components/Breadcrumbs/index.js.map +1 -1
  6. package/dist/components/Button/index.d.ts +1 -4
  7. package/dist/components/Button/index.d.ts.map +1 -1
  8. package/dist/components/Button/index.js +11 -26
  9. package/dist/components/Button/index.js.map +1 -1
  10. package/dist/components/Collection/index.d.ts +2 -2
  11. package/dist/components/Collection/index.d.ts.map +1 -1
  12. package/dist/components/Collection/index.js +10 -10
  13. package/dist/components/Collection/index.js.map +1 -1
  14. package/dist/components/Collection/item.d.ts +3 -3
  15. package/dist/components/Collection/item.d.ts.map +1 -1
  16. package/dist/components/Collection/item.js.map +1 -1
  17. package/dist/components/Columns/index.d.ts +1 -1
  18. package/dist/components/Columns/index.d.ts.map +1 -1
  19. package/dist/components/Comment/index.d.ts +1 -1
  20. package/dist/components/Comment/index.d.ts.map +1 -1
  21. package/dist/components/CommentFeed/index.d.ts +1 -1
  22. package/dist/components/CommentFeed/index.d.ts.map +1 -1
  23. package/dist/components/ControlGroup/index.d.ts +1 -1
  24. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  25. package/dist/components/Dropdown/index.d.ts +1 -1
  26. package/dist/components/Dropdown/index.d.ts.map +1 -1
  27. package/dist/components/Dropdown/item.d.ts +2 -2
  28. package/dist/components/Dropdown/item.d.ts.map +1 -1
  29. package/dist/components/Dropdown/list.d.ts +1 -1
  30. package/dist/components/Dropdown/list.d.ts.map +1 -1
  31. package/dist/components/Effect/index.d.ts +2 -2
  32. package/dist/components/Effect/index.d.ts.map +1 -1
  33. package/dist/components/ExportModal/index.d.ts +11 -0
  34. package/dist/components/ExportModal/index.d.ts.map +1 -0
  35. package/dist/components/ExportModal/index.js +91 -0
  36. package/dist/components/ExportModal/index.js.map +1 -0
  37. package/dist/components/Header/index.d.ts +7 -7
  38. package/dist/components/Header/index.d.ts.map +1 -1
  39. package/dist/components/InputClearButton/index.d.ts +1 -0
  40. package/dist/components/InputClearButton/index.d.ts.map +1 -1
  41. package/dist/components/InternalPopover/index.js +2 -2
  42. package/dist/components/InternalPopover/index.js.map +1 -1
  43. package/dist/components/KeyValueTable/index.d.ts +7 -4
  44. package/dist/components/KeyValueTable/index.d.ts.map +1 -1
  45. package/dist/components/KeyValueTable/index.js +32 -2
  46. package/dist/components/KeyValueTable/index.js.map +1 -1
  47. package/dist/components/Layout/content.d.ts +1 -1
  48. package/dist/components/Layout/content.d.ts.map +1 -1
  49. package/dist/components/Layout/index.d.ts +1 -1
  50. package/dist/components/Layout/index.d.ts.map +1 -1
  51. package/dist/components/Menu/item.d.ts +1 -1
  52. package/dist/components/Menu/item.d.ts.map +1 -1
  53. package/dist/components/Menu/item.js +3 -3
  54. package/dist/components/Menu/item.js.map +1 -1
  55. package/dist/components/Message/index.d.ts +1 -0
  56. package/dist/components/Message/index.d.ts.map +1 -1
  57. package/dist/components/Message/index.js.map +1 -1
  58. package/dist/components/Modal/index.d.ts +1 -1
  59. package/dist/components/Modal/index.d.ts.map +1 -1
  60. package/dist/components/MultiSelect/index.d.ts +2 -2
  61. package/dist/components/MultiSelect/index.d.ts.map +1 -1
  62. package/dist/components/Notifications/notification.d.ts +1 -0
  63. package/dist/components/Notifications/notification.d.ts.map +1 -1
  64. package/dist/components/Notifications/notification.js +23 -16
  65. package/dist/components/Notifications/notification.js.map +1 -1
  66. package/dist/components/Paging/index.d.ts +1 -1
  67. package/dist/components/Paging/index.d.ts.map +1 -1
  68. package/dist/components/Panel/NonResponsiveActions.d.ts +1 -1
  69. package/dist/components/Panel/NonResponsiveActions.d.ts.map +1 -1
  70. package/dist/components/Panel/index.js +1 -1
  71. package/dist/components/Panel/index.js.map +1 -1
  72. package/dist/components/Panel/panel.screenshot.d.ts +1 -1
  73. package/dist/components/Panel/panel.screenshot.d.ts.map +1 -1
  74. package/dist/components/Paragraph/index.d.ts +1 -1
  75. package/dist/components/Paragraph/index.d.ts.map +1 -1
  76. package/dist/components/Popover/index.d.ts +1 -1
  77. package/dist/components/Popover/index.d.ts.map +1 -1
  78. package/dist/components/Popover/index.js +2 -0
  79. package/dist/components/Popover/index.js.map +1 -1
  80. package/dist/components/RadioGroup/index.d.ts +1 -1
  81. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  82. package/dist/components/Sidebar/item.d.ts +1 -1
  83. package/dist/components/Sidebar/item.d.ts.map +1 -1
  84. package/dist/components/Spacer/index.d.ts +3 -3
  85. package/dist/components/Spacer/index.d.ts.map +1 -1
  86. package/dist/components/Spinner/index.d.ts +1 -1
  87. package/dist/components/Spinner/index.d.ts.map +1 -1
  88. package/dist/components/Table/body.d.ts +1 -1
  89. package/dist/components/Table/body.d.ts.map +1 -1
  90. package/dist/components/Table/body.js +26 -21
  91. package/dist/components/Table/body.js.map +1 -1
  92. package/dist/components/Table/cell.d.ts +3 -2
  93. package/dist/components/Table/cell.d.ts.map +1 -1
  94. package/dist/components/Table/cell.js +8 -4
  95. package/dist/components/Table/cell.js.map +1 -1
  96. package/dist/components/Table/headerCell.d.ts +1 -1
  97. package/dist/components/Table/headerCell.d.ts.map +1 -1
  98. package/dist/components/Table/helpers.d.ts +8 -6
  99. package/dist/components/Table/helpers.d.ts.map +1 -1
  100. package/dist/components/Table/helpers.js +49 -16
  101. package/dist/components/Table/helpers.js.map +1 -1
  102. package/dist/components/Table/index.d.ts +5 -4
  103. package/dist/components/Table/index.d.ts.map +1 -1
  104. package/dist/components/Table/index.js +47 -38
  105. package/dist/components/Table/index.js.map +1 -1
  106. package/dist/components/Table/row.d.ts +7 -5
  107. package/dist/components/Table/row.d.ts.map +1 -1
  108. package/dist/components/Table/row.js +38 -36
  109. package/dist/components/Table/row.js.map +1 -1
  110. package/dist/components/Table/value.d.ts +1 -1
  111. package/dist/components/Table/value.d.ts.map +1 -1
  112. package/dist/components/Tabs/content.d.ts +1 -1
  113. package/dist/components/Tabs/content.d.ts.map +1 -1
  114. package/dist/components/Tabs/index.d.ts +1 -1
  115. package/dist/components/Tabs/index.d.ts.map +1 -1
  116. package/dist/components/Tabs/list.d.ts +1 -1
  117. package/dist/components/Tabs/list.d.ts.map +1 -1
  118. package/dist/components/Tabs/list.js +1 -1
  119. package/dist/components/Tabs/list.js.map +1 -1
  120. package/dist/components/Tag/group.d.ts +1 -1
  121. package/dist/components/Tag/group.d.ts.map +1 -1
  122. package/dist/components/Tree/index.d.ts +2 -1
  123. package/dist/components/Tree/index.d.ts.map +1 -1
  124. package/dist/components/Tree/index.js +35 -31
  125. package/dist/components/Tree/index.js.map +1 -1
  126. package/dist/constants/sizes.js +5 -5
  127. package/dist/containers/Paging.d.ts +1 -1
  128. package/dist/containers/Paging.d.ts.map +1 -1
  129. package/dist/containers/ThemeProvider.d.ts +1 -1
  130. package/dist/containers/ThemeProvider.d.ts.map +1 -1
  131. package/dist/helpers/utils.d.ts +2 -1
  132. package/dist/helpers/utils.d.ts.map +1 -1
  133. package/dist/helpers/utils.js +20 -2
  134. package/dist/helpers/utils.js.map +1 -1
  135. package/dist/hooks/useAutoFocus.d.ts +1 -1
  136. package/dist/hooks/useAutoFocus.d.ts.map +1 -1
  137. package/dist/hooks/usePopover.d.ts +1 -0
  138. package/dist/hooks/usePopover.d.ts.map +1 -1
  139. package/dist/index.d.ts +1 -1
  140. package/dist/index.d.ts.map +1 -1
  141. package/dist/index.js.map +1 -1
  142. package/dist/styles.d.ts +3 -0
  143. package/dist/styles.d.ts.map +1 -1
  144. package/dist/styles.js +49 -11
  145. package/dist/styles.js.map +1 -1
  146. package/migration-storybook.log +88 -0
  147. package/package.json +26 -20
  148. package/src/components/Breadcrumbs/index.tsx +1 -1
  149. package/src/components/Button/index.tsx +3 -54
  150. package/src/components/Collection/index.tsx +18 -15
  151. package/src/components/Collection/item.tsx +2 -1
  152. package/src/components/ExportModal/index.tsx +98 -0
  153. package/src/components/InternalPopover/index.tsx +2 -2
  154. package/src/components/KeyValueTable/index.tsx +59 -11
  155. package/src/components/Menu/item.tsx +4 -4
  156. package/src/components/Message/index.tsx +1 -0
  157. package/src/components/Notifications/notification.tsx +14 -3
  158. package/src/components/Panel/index.tsx +2 -2
  159. package/src/components/Popover/index.tsx +3 -0
  160. package/src/components/Table/body.tsx +26 -20
  161. package/src/components/Table/cell.tsx +15 -4
  162. package/src/components/Table/helpers.ts +52 -21
  163. package/src/components/Table/index.tsx +119 -75
  164. package/src/components/Table/row.tsx +47 -46
  165. package/src/components/Tabs/list.tsx +1 -1
  166. package/src/components/Tree/index.tsx +82 -75
  167. package/src/constants/sizes.ts +5 -5
  168. package/src/helpers/utils.ts +10 -2
  169. package/src/hooks/useAutoFocus.ts +1 -1
  170. package/src/index.tsx +1 -1
  171. package/src/mock/tableData.ts +12 -0
  172. package/src/stories/Breadcrumbs/Breadcrumbs.stories.tsx +11 -23
  173. package/src/stories/Button/Button.stories.tsx +83 -47
  174. package/src/stories/Checkbox/Checkbox.stories.tsx +19 -9
  175. package/src/stories/Collection/Collection.stories.tsx +195 -171
  176. package/src/stories/Columns/Columns.stories.tsx +38 -24
  177. package/src/stories/Comment/Comment.stories.tsx +15 -6
  178. package/src/stories/ControlGroup/ControlGroup.stories.tsx +102 -48
  179. package/src/stories/Drawer/Drawer.stories.tsx +52 -17
  180. package/src/stories/Dropdown/Dropdown.stories.tsx +184 -152
  181. package/src/stories/ExportModal/ExportModal.stories.tsx +18 -0
  182. package/src/stories/Header/Header.stories.tsx +65 -31
  183. package/src/stories/Icon/Icon.stories.tsx +139 -133
  184. package/src/stories/Input/Input.stories.tsx +68 -31
  185. package/src/stories/KeyValueTable/KeyValueTable.stories.tsx +183 -117
  186. package/src/stories/Menu/Menu.stories.tsx +56 -20
  187. package/src/stories/Message/Message.stories.tsx +96 -37
  188. package/src/stories/Modal/Modal.stories.tsx +28 -8
  189. package/src/stories/MultiSelect/MultiSelect.stories.tsx +66 -35
  190. package/src/stories/Navbar/Navbar.stories.tsx +15 -5
  191. package/src/stories/Notifications/Interactive.stories.tsx +40 -28
  192. package/src/stories/Notifications/Notification.stories.tsx +55 -41
  193. package/src/stories/Notifications/Notifications.stories.tsx +45 -29
  194. package/src/stories/Paging/Paging.stories.tsx +206 -177
  195. package/src/stories/Panel/Panel.stories.tsx +238 -168
  196. package/src/stories/Paragraph/Paragraph.stories.tsx +66 -31
  197. package/src/stories/Popover/Popover.stories.tsx +62 -40
  198. package/src/stories/RadioGroup/RadioGroup.stories.tsx +41 -19
  199. package/src/stories/Sidebar/Sidebar.stories.tsx +29 -10
  200. package/src/stories/Spacer/Spacer.stories.tsx +13 -5
  201. package/src/stories/Spinner/Spinner.stories.tsx +26 -12
  202. package/src/stories/Table/Table.stories.tsx +200 -144
  203. package/src/stories/Table/Tests.stories.tsx +9 -0
  204. package/src/stories/Tabs/Tabs.stories.tsx +82 -46
  205. package/src/stories/Tag/Tag.stories.tsx +56 -37
  206. package/src/stories/Tag/TagGroup.stories.tsx +297 -0
  207. package/src/stories/TextArea/TextArea.stories.tsx +82 -40
  208. package/src/stories/Tree/Tree.stories.tsx +84 -22
  209. package/src/stories/utils.ts +22 -1
  210. package/src/styles.ts +55 -2
  211. package/tests.json +1 -1
@@ -28,9 +28,10 @@ export interface IReqoreCollectionItemProps
28
28
  | 'isCollapsed'
29
29
  | 'unMountContentOnCollapse'
30
30
  | 'bottomActions'
31
+ | 'content'
31
32
  > {
32
33
  selected?: boolean;
33
- content?: string | React.ReactNode;
34
+ content?: string | number | React.ReactNode;
34
35
  expandable?: boolean;
35
36
  expandedContent?: string | React.ReactNode;
36
37
  expandedActions?: IReqorePanelBottomAction[];
@@ -0,0 +1,98 @@
1
+ import { useCallback, useMemo, useState } from 'react';
2
+ import { stringify } from 'yaml';
3
+ import { ReqoreTextarea, useReqoreProperty } from '../..';
4
+ import { convertToCSV } from '../../helpers/utils';
5
+ import { IReqoreModalProps, ReqoreModal } from '../Modal';
6
+ import ReqoreTabs, { IReqoreTabsProps } from '../Tabs';
7
+ import ReqoreTabsContent from '../Tabs/content';
8
+
9
+ export interface IReqoreExportModalProps extends IReqoreModalProps {
10
+ data: { [key: string]: any } | any[];
11
+ sendNotificationOnCopy?: boolean;
12
+ tabsOptions?: Omit<IReqoreTabsProps, 'tabs'>;
13
+ }
14
+
15
+ export const ReqoreExportModal = ({
16
+ data,
17
+ sendNotificationOnCopy = true,
18
+ tabsOptions = {},
19
+ ...rest
20
+ }: IReqoreExportModalProps) => {
21
+ const addNotification = useReqoreProperty('addNotification');
22
+ const isArray = Array.isArray(data);
23
+ const [tab, setTab] = useState<string>(isArray ? 'csv' : 'json');
24
+ const tabs: IReqoreTabsProps['tabs'] = [
25
+ { label: 'CSV', id: 'csv', disabled: !isArray },
26
+ { label: 'JSON', id: 'json' },
27
+ { label: 'YAML', id: 'yaml' },
28
+ ];
29
+
30
+ const dataToExport = useMemo(() => {
31
+ switch (tab) {
32
+ case 'csv':
33
+ return convertToCSV(data as any[]);
34
+ case 'json':
35
+ return JSON.stringify(data, null, 2);
36
+ case 'yaml':
37
+ return stringify(data, null, 2);
38
+ default:
39
+ return '';
40
+ }
41
+ }, [data, tab, isArray]);
42
+
43
+ const handleCopyClick = useCallback(() => {
44
+ navigator.clipboard.writeText(dataToExport);
45
+
46
+ if (sendNotificationOnCopy) {
47
+ addNotification({
48
+ content: 'Data copied to clipboard',
49
+ intent: 'success',
50
+ duration: 3000,
51
+ });
52
+ }
53
+ }, [sendNotificationOnCopy, dataToExport]);
54
+
55
+ return (
56
+ <ReqoreModal
57
+ label='Export data'
58
+ icon='DownloadLine'
59
+ {...rest}
60
+ isOpen
61
+ bottomActions={[
62
+ {
63
+ position: 'right',
64
+ label: 'Copy',
65
+ icon: 'ClipboardLine',
66
+ onClick: () => {
67
+ handleCopyClick();
68
+ },
69
+ },
70
+ {
71
+ position: 'right',
72
+ label: 'Copy and close',
73
+ icon: 'ClipboardFill',
74
+ onClick: () => {
75
+ handleCopyClick();
76
+ rest.onClose?.();
77
+ },
78
+ },
79
+ ]}
80
+ >
81
+ <ReqoreTabs
82
+ fillParent
83
+ activeTabIntent='info'
84
+ activeTab={isArray ? 'csv' : 'json'}
85
+ padded={false}
86
+ {...tabsOptions}
87
+ onTabChange={(tabId) => setTab(tabId.toString())}
88
+ tabs={tabs}
89
+ >
90
+ {tabs.map((tab) => (
91
+ <ReqoreTabsContent tabId={tab.id} key={tab.id} padded='none'>
92
+ <ReqoreTextarea readOnly value={dataToExport} scaleWithContent minimal />
93
+ </ReqoreTabsContent>
94
+ ))}
95
+ </ReqoreTabs>
96
+ </ReqoreModal>
97
+ );
98
+ };
@@ -59,8 +59,8 @@ const StyledPopoverArrow = styled.div<{ theme: IReqoreTheme }>`
59
59
 
60
60
  const StyledPopoverWrapper = styled.div<{ theme: IReqoreTheme }>`
61
61
  animation: 0.2s ${fadeIn} ease-out;
62
- max-width: ${({ maxWidth = '80vw' }) => maxWidth};
63
- max-height: ${({ maxHeight = '80vh' }) => maxHeight};
62
+ max-width: ${({ maxWidth }) => maxWidth};
63
+ max-height: ${({ maxHeight }) => maxHeight};
64
64
  z-index: 999999;
65
65
  border-radius: ${RADIUS_FROM_SIZE.normal}px;
66
66
  border: ${({ flat, noWrapper, ...rest }: any) =>
@@ -1,14 +1,11 @@
1
1
  import { keys } from 'lodash';
2
2
  import { useMemo } from 'react';
3
+ import { SIZE_TO_PX } from '../../constants/sizes';
3
4
  import { TReqoreIntent } from '../../constants/theme';
4
5
  import { IReqoreIconName } from '../../types/icons';
6
+ import { IReqoreButtonProps } from '../Button';
5
7
  import { IReqorePanelProps } from '../Panel';
6
- import ReqoreTable, {
7
- IReqoreTableColumn,
8
- IReqoreTableProps,
9
- IReqoreTableRowData,
10
- TReqoreTableColumnContent,
11
- } from '../Table';
8
+ import ReqoreTable, { IReqoreTableColumn, IReqoreTableProps, IReqoreTableRowData } from '../Table';
12
9
  import { IReqoreTableValueProps, ReqoreTableValue } from '../Table/value';
13
10
 
14
11
  export type TReqoreKeyValueTablePrimitiveValue = string | number | boolean | null | undefined;
@@ -19,7 +16,21 @@ export type TReqoreKeyValueTableValue =
19
16
 
20
17
  export interface IReqoreKeyValueTableProps
21
18
  extends IReqorePanelProps,
22
- Pick<IReqoreTableProps, 'striped' | 'width' | 'height' | 'fill'> {
19
+ Pick<
20
+ IReqoreTableProps,
21
+ | 'striped'
22
+ | 'width'
23
+ | 'height'
24
+ | 'fill'
25
+ | 'filterable'
26
+ | 'exportable'
27
+ | 'filter'
28
+ | 'onFilterChange'
29
+ | 'filterProps'
30
+ | 'zoomable'
31
+ | 'wrapperSize'
32
+ | 'paging'
33
+ > {
23
34
  data: { [key: string | number]: TReqoreKeyValueTableValue };
24
35
 
25
36
  keyLabel?: string;
@@ -28,6 +39,10 @@ export interface IReqoreKeyValueTableProps
28
39
  keyAlign?: IReqoreTableColumn['align'];
29
40
  maxKeyWidth?: number;
30
41
 
42
+ sortable?: boolean;
43
+
44
+ rowActions?: (key: string, value: TReqoreKeyValueTableValue) => IReqoreButtonProps[];
45
+
31
46
  valueLabel?: string;
32
47
  valueIcon?: IReqoreIconName;
33
48
  valueAlign?: IReqoreTableColumn['align'];
@@ -36,10 +51,8 @@ export interface IReqoreKeyValueTableProps
36
51
 
37
52
  valueRenderer?: (
38
53
  data: IReqoreTableRowData,
39
- defaultComponent?: ({
40
- value,
41
- }: IReqoreTableValueProps) => TReqoreTableColumnContent | JSX.Element
42
- ) => JSX.Element;
54
+ defaultComponent?: ({ value }: IReqoreTableValueProps) => any
55
+ ) => any;
43
56
  }
44
57
 
45
58
  export const ReqoreKeyValueTable = ({
@@ -55,6 +68,8 @@ export const ReqoreKeyValueTable = ({
55
68
  keyAlign = 'left',
56
69
  valueAlign = 'left',
57
70
  defaultValueFilter,
71
+ sortable,
72
+ rowActions,
58
73
  ...rest
59
74
  }: IReqoreKeyValueTableProps) => {
60
75
  const { columns, items } = useMemo(() => {
@@ -62,6 +77,7 @@ export const ReqoreKeyValueTable = ({
62
77
  {
63
78
  dataId: 'tableKey',
64
79
  grow: 1,
80
+ sortable,
65
81
  width: maxKeyWidth < 150 ? maxKeyWidth : 150,
66
82
  pin: 'left',
67
83
  hideable: false,
@@ -81,6 +97,7 @@ export const ReqoreKeyValueTable = ({
81
97
  {
82
98
  dataId: 'value',
83
99
  grow: 3,
100
+ sortable,
84
101
  hideable: false,
85
102
  filterable: true,
86
103
  pinnable: false,
@@ -94,12 +111,34 @@ export const ReqoreKeyValueTable = ({
94
111
  },
95
112
 
96
113
  cell: {
114
+ tooltip: (value) => ({
115
+ content: JSON.stringify(value),
116
+ noArrow: true,
117
+ useTargetWidth: true,
118
+ }),
97
119
  content: (data) =>
98
120
  valueRenderer?.(data, ReqoreTableValue) || <ReqoreTableValue value={data.value} />,
99
121
  },
100
122
  },
101
123
  ];
102
124
 
125
+ if (rowActions) {
126
+ columns.push({
127
+ dataId: 'actions',
128
+ hideable: false,
129
+ pin: 'right',
130
+ header: {
131
+ icon: 'SettingsLine',
132
+ },
133
+ width: SIZE_TO_PX[rest.size || 'normal'] * 2,
134
+ align: 'center',
135
+ cell: {
136
+ padded: 'none',
137
+ actions: (data) => rowActions(data.tableKey, data.value),
138
+ },
139
+ });
140
+ }
141
+
103
142
  let items: IReqoreTableRowData[] = [];
104
143
 
105
144
  keys(data).map((key) => {
@@ -117,6 +156,15 @@ export const ReqoreKeyValueTable = ({
117
156
  columns={columns}
118
157
  data={items}
119
158
  {...rest}
159
+ sort={
160
+ sortable
161
+ ? {
162
+ by: 'tableKey',
163
+ thenBy: 'value',
164
+ direction: 'asc',
165
+ }
166
+ : undefined
167
+ }
120
168
  className={`${rest.className || ''} reqore-key-value-table`}
121
169
  />
122
170
  );
@@ -17,7 +17,7 @@ export interface IReqoreMenuItemProps
17
17
  selected?: boolean;
18
18
  itemId?: string;
19
19
  onRightIconClick?: (itemId?: string, event?: React.MouseEvent<HTMLElement>) => void;
20
- onClick?: (itemId?: string, event?: React.MouseEvent<HTMLElement>) => void;
20
+ onClick?: (event: React.MouseEvent<HTMLElement>, itemId?: string) => void;
21
21
  scrollIntoView?: boolean;
22
22
  }
23
23
 
@@ -59,12 +59,12 @@ const ReqoreMenuItem = forwardRef<HTMLButtonElement, IReqoreMenuItemProps>(
59
59
  ) => {
60
60
  const { removePopover } = useContext(PopoverContext);
61
61
  const { targetRef } = useCombinedRefs<HTMLButtonElement>(ref);
62
- const [itemRef, setItemRef] = useState<HTMLButtonElement>(undefined);
62
+ const [itemRef, setItemRef] = useState<HTMLButtonElement | null>(null);
63
63
 
64
64
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
65
65
  event.persist();
66
66
 
67
- onClick?.(itemId, event);
67
+ onClick?.(event, itemId);
68
68
 
69
69
  if (_insidePopover && _popoverId) {
70
70
  removePopover!(_popoverId);
@@ -102,7 +102,7 @@ const ReqoreMenuItem = forwardRef<HTMLButtonElement, IReqoreMenuItemProps>(
102
102
  onClick={handleClick}
103
103
  active={selected}
104
104
  ref={(ref) => {
105
- targetRef.current = ref;
105
+ targetRef.current = ref || undefined;
106
106
  setItemRef(ref);
107
107
  }}
108
108
  disabled={disabled}
@@ -52,6 +52,7 @@ export interface IReqoreMessageProps
52
52
  onFinish?: () => any;
53
53
  flat?: boolean;
54
54
  hasShadow?: boolean;
55
+ margin?: 'top' | 'bottom' | 'both' | 'none';
55
56
  }
56
57
 
57
58
  export interface IReqoreNotificationStyle extends IReqoreMessageProps {
@@ -61,6 +61,7 @@ export interface IReqoreNotificationStyle extends IWithReqoreOpaque {
61
61
  minimal?: boolean;
62
62
  size?: TSizes;
63
63
  asMessage?: boolean;
64
+ margin?: 'top' | 'bottom' | 'both' | 'none';
64
65
  }
65
66
 
66
67
  const timeoutAnimation = keyframes`
@@ -84,6 +85,15 @@ export const StyledReqoreNotification = styled(StyledEffect)<IReqoreNotification
84
85
  position: relative;
85
86
  transition: all 0.2s ease-out;
86
87
 
88
+ ${({ margin, size = 'normal' }) => css`
89
+ margin-top: ${margin === 'top' || margin === 'both'
90
+ ? `${PADDING_FROM_SIZE[size]}px`
91
+ : undefined};
92
+ margin-bottom: ${margin === 'bottom' || margin === 'both'
93
+ ? `${PADDING_FROM_SIZE[size]}px`
94
+ : undefined};
95
+ `};
96
+
87
97
  // Do not fade in the component if it's a message
88
98
  ${({ asMessage }) => {
89
99
  if (asMessage) {
@@ -95,7 +105,8 @@ export const StyledReqoreNotification = styled(StyledEffect)<IReqoreNotification
95
105
  }}
96
106
 
97
107
  &:not(:first-child) {
98
- margin-top: ${({ asMessage }) => (asMessage ? undefined : `10px`)};
108
+ margin-top: ${({ asMessage, size }) =>
109
+ asMessage ? undefined : `${PADDING_FROM_SIZE[size]}px`};
99
110
  }
100
111
 
101
112
  ${({
@@ -236,7 +247,7 @@ const ReqoreNotification = forwardRef<HTMLDivElement, IReqoreNotificationProps>(
236
247
  onFinish,
237
248
  flat,
238
249
  minimal,
239
- opaque,
250
+ opaque = true,
240
251
  size = 'normal',
241
252
  customTheme,
242
253
  },
@@ -287,7 +298,7 @@ const ReqoreNotification = forwardRef<HTMLDivElement, IReqoreNotificationProps>(
287
298
  hasShadow
288
299
  timeout={duration}
289
300
  clickable={!!onClick}
290
- onClick={onClick}
301
+ onClick={() => onClick?.()}
291
302
  flat={flat}
292
303
  minimal={minimal}
293
304
  className='reqore-notification'
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import { size } from 'lodash';
2
+ import { isArray, size } from 'lodash';
3
3
  import { darken, rgba } from 'polished';
4
4
  import { ReactElement, forwardRef, useCallback, useMemo, useState } from 'react';
5
5
  import { useMeasure, useUpdateEffect } from 'react-use';
@@ -379,7 +379,7 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
379
379
  collapsible ||
380
380
  !!onClose ||
381
381
  !!size(actions.filter(isActionShown)) ||
382
- !!badge ||
382
+ !!(isArray(badge) ? size(badge) : badge) ||
383
383
  !!icon,
384
384
  [label, collapsible, onClose, actions, badge, icon]
385
385
  );
@@ -31,6 +31,8 @@ const Popover = memo(
31
31
  }: IReqorePopoverProps) => {
32
32
  const [ref, setRef] = useState(undefined);
33
33
 
34
+ console.log(rest);
35
+
34
36
  const popoverData: IPopoverControls = usePopover({ targetElement: ref, ...rest });
35
37
 
36
38
  useEffect(() => {
@@ -38,6 +40,7 @@ const Popover = memo(
38
40
  }, [popoverData]);
39
41
 
40
42
  if (isReqoreComponent) {
43
+ console.log(Component);
41
44
  return (
42
45
  <Component
43
46
  {...componentProps}
@@ -1,3 +1,4 @@
1
+ import count from 'lodash/size';
1
2
  import { forwardRef, useMemo } from 'react';
2
3
  import { useMount } from 'react-use';
3
4
  import { FixedSizeList as List } from 'react-window';
@@ -14,7 +15,7 @@ export interface IReqoreTableSectionBodyProps extends IReqoreTableRowOptions {
14
15
  main: React.RefObject<HTMLDivElement>;
15
16
  header: React.RefObject<HTMLDivElement>;
16
17
  };
17
- type?: 'left' | 'right' | 'main';
18
+ type: 'left' | 'right' | 'main';
18
19
  onScrollChange?: (isScrolled: boolean) => void;
19
20
  }
20
21
 
@@ -41,29 +42,32 @@ const ReqoreTableBody = forwardRef<HTMLDivElement, IReqoreTableSectionBodyProps>
41
42
 
42
43
  useMount(() => {
43
44
  targetRef.current?.addEventListener('wheel', (e) => {
44
- if (e.deltaY) {
45
- e.preventDefault();
45
+ // Only scroll if the element is scrollable
46
+ if (refs[type].current?.scrollHeight > refs[type].current?.clientHeight) {
47
+ if (e.deltaY) {
48
+ e.preventDefault();
46
49
 
47
- const currentScroll = refs[type].current?.scrollTop + e.deltaY;
50
+ const currentScroll = refs[type].current?.scrollTop + e.deltaY;
48
51
 
49
- onScrollChange?.(currentScroll > 0);
52
+ onScrollChange?.(currentScroll > 0);
50
53
 
51
- refs[type].current?.scrollTo({ top: currentScroll });
54
+ refs[type].current?.scrollTo({ top: currentScroll });
52
55
 
53
- if (type === 'left') {
54
- refs.main.current?.scrollTo({ top: refs.main.current?.scrollTop + e.deltaY });
55
- refs.right.current?.scrollTo({ top: refs.right.current?.scrollTop + e.deltaY });
56
- } else if (type === 'main') {
57
- refs.left.current?.scrollTo({ top: refs.left.current?.scrollTop + e.deltaY });
58
- refs.right.current?.scrollTo({ top: refs.right.current?.scrollTop + e.deltaY });
59
- } else if (type === 'right') {
60
- refs.main.current?.scrollTo({ top: refs.main.current?.scrollTop + e.deltaY });
61
- refs.left.current?.scrollTo({ top: refs.left.current?.scrollTop + e.deltaY });
56
+ if (type === 'left') {
57
+ refs.main.current?.scrollTo({ top: refs.main.current?.scrollTop + e.deltaY });
58
+ refs.right.current?.scrollTo({ top: refs.right.current?.scrollTop + e.deltaY });
59
+ } else if (type === 'main') {
60
+ refs.left.current?.scrollTo({ top: refs.left.current?.scrollTop + e.deltaY });
61
+ refs.right.current?.scrollTo({ top: refs.right.current?.scrollTop + e.deltaY });
62
+ } else if (type === 'right') {
63
+ refs.main.current?.scrollTo({ top: refs.main.current?.scrollTop + e.deltaY });
64
+ refs.left.current?.scrollTo({ top: refs.left.current?.scrollTop + e.deltaY });
65
+ }
62
66
  }
63
- }
64
67
 
65
- if (e.deltaX && type === 'main') {
66
- refs.header.current?.scrollTo({ left: refs.main.current?.scrollLeft + e.deltaX });
68
+ if (e.deltaX && type === 'main') {
69
+ refs.header.current?.scrollTo({ left: refs.main.current?.scrollLeft + e.deltaX });
70
+ }
67
71
  }
68
72
  });
69
73
  });
@@ -73,13 +77,15 @@ const ReqoreTableBody = forwardRef<HTMLDivElement, IReqoreTableSectionBodyProps>
73
77
  [size, rest.flat]
74
78
  );
75
79
 
80
+ const itemCount = useMemo(() => count(data), [data]);
81
+
76
82
  return (
77
83
  <StyledList
78
84
  outerRef={targetRef}
79
- itemCount={data.length}
85
+ itemCount={itemCount}
80
86
  // If the defined height is less than the count of items' height
81
87
  // use that height instead
82
- height={height > data.length * rowHeight ? data.length * rowHeight : height}
88
+ height={height > itemCount * rowHeight ? itemCount * rowHeight : height}
83
89
  className='reqore-table-body'
84
90
  itemSize={rest.flat ? TABLE_SIZE_TO_PX[size] : TABLE_SIZE_TO_PX[size] + 1}
85
91
  itemData={{
@@ -1,9 +1,13 @@
1
1
  import { lighten, rgba } from 'polished';
2
+ import { forwardRef } from 'react';
2
3
  import styled, { css } from 'styled-components';
3
4
  import { IReqoreTableColumn } from '.';
4
5
  import { TEXT_FROM_SIZE } from '../../constants/sizes';
5
6
  import { changeLightness, getReadableColorFrom } from '../../helpers/colors';
6
7
  import { alignToFlexAlign } from '../../helpers/utils';
8
+ import { useCombinedRefs } from '../../hooks/useCombinedRefs';
9
+ import { useTooltip } from '../../hooks/useTooltip';
10
+ import { IWithReqoreTooltip } from '../../types/global';
7
11
  import { TReqoreColor } from '../Effect';
8
12
  import { IReqoreTableCellStyle } from './row';
9
13
 
@@ -11,7 +15,8 @@ export interface IReqoreCustomTableBodyCellProps extends IReqoreTableBodyCellPro
11
15
  export interface IReqoreCustomTableBodyCell extends React.FC<IReqoreCustomTableBodyCellProps> {}
12
16
  export interface IReqoreTableBodyCellProps
13
17
  extends Partial<IReqoreTableColumn>,
14
- React.HTMLAttributes<HTMLDivElement> {
18
+ React.HTMLAttributes<HTMLDivElement>,
19
+ IWithReqoreTooltip {
15
20
  children?: React.ReactNode;
16
21
  padded?: IReqoreTableColumn['cell']['padded'];
17
22
  }
@@ -118,6 +123,12 @@ export const StyledTableCell = styled.div<IReqoreTableCellStyle>`
118
123
  }}
119
124
  `;
120
125
 
121
- export const ReqoreTableBodyCell = (props: IReqoreTableBodyCellProps) => {
122
- return <StyledTableCell {...props} />;
123
- };
126
+ export const ReqoreTableBodyCell = forwardRef<HTMLButtonElement, IReqoreTableBodyCellProps>(
127
+ (props: IReqoreTableBodyCellProps, ref) => {
128
+ const { targetRef } = useCombinedRefs(ref);
129
+
130
+ useTooltip(targetRef.current, props.tooltip);
131
+
132
+ return <StyledTableCell {...props} ref={targetRef} />;
133
+ }
134
+ );
@@ -1,15 +1,15 @@
1
1
  import { size } from 'lodash';
2
2
  import { firstBy } from 'thenby';
3
- import { IReqoreTableColumn, IReqoreTableSort } from '.';
3
+ import { IReqoreTableColumn, IReqoreTableData, IReqoreTableSort } from '.';
4
4
  import { ICON_FROM_SIZE, SIZE_TO_MODIFIER, SIZE_TO_PX, TSizes } from '../../constants/sizes';
5
5
  import { IReqoreIconName } from '../../types/icons';
6
- import { IReqorePanelAction } from '../Panel';
6
+ import { IReqorePanelSubAction } from '../Panel';
7
7
 
8
8
  export const flipSortDirection = (direction: 'asc' | 'desc'): 'asc' | 'desc' =>
9
9
  direction === 'asc' ? 'desc' : 'asc';
10
10
 
11
- export const fixSort = (sort?: IReqoreTableSort) => {
12
- return { ...(sort || {}), direction: sort?.direction || 'desc' };
11
+ export const fixSort = (sort: IReqoreTableSort) => {
12
+ return { ...sort, direction: sort?.direction || 'desc' };
13
13
  };
14
14
 
15
15
  export const sortTableData = (data: any[], sort: IReqoreTableSort) => {
@@ -81,20 +81,38 @@ export const zoomToWidth = {
81
81
 
82
82
  // This code converts a zoom level to a label.
83
83
  export const zoomToLabel = {
84
- 0: '0.6x',
85
- 0.5: '0.8x',
86
- 1: '1x',
87
- 1.5: '1.2x',
88
- 2: '1.4x',
84
+ 0: '30%',
85
+ 0.5: '60%',
86
+ 1: '100%',
87
+ 1.5: '130%',
88
+ 2: '160%',
89
89
  };
90
90
 
91
+ export const getExportActions = (
92
+ onClick: (type: 'current' | 'full') => void,
93
+ withLabels: boolean = true
94
+ ): IReqorePanelSubAction[] => [
95
+ {
96
+ label: withLabels ? 'Export current view' : undefined,
97
+ icon: 'Download2Line',
98
+ onClick: () => onClick('current'),
99
+ },
100
+ {
101
+ label: withLabels ? 'Export full data' : undefined,
102
+ icon: 'DownloadLine',
103
+ onClick: () => onClick('full'),
104
+ },
105
+ ];
106
+
91
107
  export const getZoomActions = (
92
108
  type: string,
93
109
  zoom: number,
94
- setter: (zoom: number) => void
95
- ): IReqorePanelAction[] => [
110
+ setter: (zoom: number) => void,
111
+ withLabels?: boolean
112
+ ): IReqorePanelSubAction[] => [
96
113
  {
97
114
  icon: 'ZoomInLine',
115
+ label: withLabels ? 'Zoom in' : undefined,
98
116
  tooltip: 'Zoom in',
99
117
  disabled: zoom === 2,
100
118
  className: `${type}-zoom-in`,
@@ -104,7 +122,7 @@ export const getZoomActions = (
104
122
  },
105
123
  {
106
124
  icon: 'RestartLine',
107
- label: zoomToLabel[zoom],
125
+ label: `${zoomToLabel[zoom]}${withLabels ? ' (reset)' : ''}`,
108
126
  tooltip: 'Reset zoom',
109
127
  disabled: zoom === 1,
110
128
  className: `${type}-zoom-reset`,
@@ -115,6 +133,7 @@ export const getZoomActions = (
115
133
  {
116
134
  icon: 'ZoomOutLine',
117
135
  tooltip: 'Zoom out',
136
+ label: withLabels ? 'Zoom out' : undefined,
118
137
  disabled: zoom === 0,
119
138
  className: `${type}-zoom-out`,
120
139
  onClick: () => {
@@ -127,7 +146,7 @@ export const getColumnsCount = (columns: IReqoreTableColumn[]): number => {
127
146
  let count = 0;
128
147
 
129
148
  columns.forEach((column) => {
130
- if (column.header.columns) {
149
+ if (column.header?.columns) {
131
150
  count += getColumnsCount(column.header.columns);
132
151
  } else {
133
152
  count += 1;
@@ -145,7 +164,7 @@ export const hasGroupedColumns = (columns: IReqoreTableColumn[]): boolean => {
145
164
 
146
165
  export const hasHiddenColumns = (columns: IReqoreTableColumn[]): boolean => {
147
166
  return columns.some((column) => {
148
- if (column.header.columns) {
167
+ if (column.header?.columns) {
149
168
  return column.header.columns.some((subColumn) => subColumn.show === false);
150
169
  }
151
170
 
@@ -157,8 +176,8 @@ export const getColumnsByPinType = (
157
176
  columns: IReqoreTableColumn[],
158
177
  type: 'left' | 'right' | 'main'
159
178
  ): IReqoreTableColumn[] => {
160
- return columns.reduce((newColumns, column) => {
161
- if (column.header.columns) {
179
+ return columns.reduce((newColumns: IReqoreTableColumn[], column): IReqoreTableColumn[] => {
180
+ if (column.header?.columns) {
162
181
  const subColumns: IReqoreTableColumn[] = getColumnsByPinType(column.header.columns, type);
163
182
 
164
183
  if (!size(subColumns)) {
@@ -188,8 +207,8 @@ export const getColumnsByPinType = (
188
207
  };
189
208
 
190
209
  export const getOnlyShownColumns = (columns: IReqoreTableColumn[]): IReqoreTableColumn[] => {
191
- return columns.reduce((newColumns, column) => {
192
- if (column.header.columns) {
210
+ return columns.reduce((newColumns: IReqoreTableColumn[], column) => {
211
+ if (column.header?.columns) {
193
212
  const subColumns = getOnlyShownColumns(column.header.columns);
194
213
 
195
214
  if (size(subColumns)) {
@@ -220,7 +239,7 @@ export const prepareColumns = (
220
239
  ): IReqoreTableColumn[] => {
221
240
  // We need to set the width of each column
222
241
  return columns.map((column) => {
223
- if (column.header.columns) {
242
+ if (column.header?.columns) {
224
243
  return {
225
244
  ...column,
226
245
  header: {
@@ -233,7 +252,7 @@ export const prepareColumns = (
233
252
  let newWidth = calculateMinimumCellWidth(
234
253
  column.width || 50,
235
254
  size,
236
- column.header.icon,
255
+ column.header?.icon,
237
256
  column.sortable,
238
257
  column.filterable,
239
258
  column.hideable,
@@ -250,7 +269,7 @@ export const prepareColumns = (
250
269
 
251
270
  export const calculateMinimumCellWidth = (
252
271
  currentWidth: number = 50,
253
- size?: TSizes,
272
+ size: TSizes,
254
273
  icon?: IReqoreIconName,
255
274
  sortable?: boolean,
256
275
  filterable?: boolean,
@@ -273,3 +292,15 @@ export const calculateMinimumCellWidth = (
273
292
 
274
293
  return width;
275
294
  };
295
+
296
+ export const removeInternalData = (data: IReqoreTableData): any[] => {
297
+ return data.map((item) => {
298
+ const newItem = { ...item };
299
+
300
+ delete newItem._selectId;
301
+ delete newItem._disabled;
302
+ delete newItem._intent;
303
+
304
+ return newItem;
305
+ });
306
+ };