@qoretechnologies/reqore 0.36.0 → 0.36.1

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 (193) 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/KeyValueTable/index.d.ts +4 -4
  42. package/dist/components/KeyValueTable/index.d.ts.map +1 -1
  43. package/dist/components/KeyValueTable/index.js.map +1 -1
  44. package/dist/components/Layout/content.d.ts +1 -1
  45. package/dist/components/Layout/content.d.ts.map +1 -1
  46. package/dist/components/Layout/index.d.ts +1 -1
  47. package/dist/components/Layout/index.d.ts.map +1 -1
  48. package/dist/components/Menu/item.d.ts +1 -1
  49. package/dist/components/Menu/item.d.ts.map +1 -1
  50. package/dist/components/Menu/item.js +3 -3
  51. package/dist/components/Menu/item.js.map +1 -1
  52. package/dist/components/Modal/index.d.ts +1 -1
  53. package/dist/components/Modal/index.d.ts.map +1 -1
  54. package/dist/components/MultiSelect/index.d.ts +2 -2
  55. package/dist/components/MultiSelect/index.d.ts.map +1 -1
  56. package/dist/components/Notifications/notification.js +3 -3
  57. package/dist/components/Notifications/notification.js.map +1 -1
  58. package/dist/components/Paging/index.d.ts +1 -1
  59. package/dist/components/Paging/index.d.ts.map +1 -1
  60. package/dist/components/Panel/NonResponsiveActions.d.ts +1 -1
  61. package/dist/components/Panel/NonResponsiveActions.d.ts.map +1 -1
  62. package/dist/components/Panel/index.js +1 -1
  63. package/dist/components/Panel/index.js.map +1 -1
  64. package/dist/components/Panel/panel.screenshot.d.ts +1 -1
  65. package/dist/components/Panel/panel.screenshot.d.ts.map +1 -1
  66. package/dist/components/Paragraph/index.d.ts +1 -1
  67. package/dist/components/Paragraph/index.d.ts.map +1 -1
  68. package/dist/components/Popover/index.d.ts +1 -1
  69. package/dist/components/Popover/index.d.ts.map +1 -1
  70. package/dist/components/RadioGroup/index.d.ts +1 -1
  71. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  72. package/dist/components/Sidebar/item.d.ts +1 -1
  73. package/dist/components/Sidebar/item.d.ts.map +1 -1
  74. package/dist/components/Spacer/index.d.ts +3 -3
  75. package/dist/components/Spacer/index.d.ts.map +1 -1
  76. package/dist/components/Spinner/index.d.ts +1 -1
  77. package/dist/components/Spinner/index.d.ts.map +1 -1
  78. package/dist/components/Table/body.d.ts +1 -1
  79. package/dist/components/Table/body.d.ts.map +1 -1
  80. package/dist/components/Table/body.js +4 -2
  81. package/dist/components/Table/body.js.map +1 -1
  82. package/dist/components/Table/cell.d.ts +1 -1
  83. package/dist/components/Table/cell.d.ts.map +1 -1
  84. package/dist/components/Table/headerCell.d.ts +1 -1
  85. package/dist/components/Table/headerCell.d.ts.map +1 -1
  86. package/dist/components/Table/helpers.d.ts +8 -6
  87. package/dist/components/Table/helpers.d.ts.map +1 -1
  88. package/dist/components/Table/helpers.js +49 -16
  89. package/dist/components/Table/helpers.js.map +1 -1
  90. package/dist/components/Table/index.d.ts +5 -4
  91. package/dist/components/Table/index.d.ts.map +1 -1
  92. package/dist/components/Table/index.js +45 -38
  93. package/dist/components/Table/index.js.map +1 -1
  94. package/dist/components/Table/row.d.ts +7 -5
  95. package/dist/components/Table/row.d.ts.map +1 -1
  96. package/dist/components/Table/row.js +3 -2
  97. package/dist/components/Table/row.js.map +1 -1
  98. package/dist/components/Table/value.d.ts +1 -1
  99. package/dist/components/Table/value.d.ts.map +1 -1
  100. package/dist/components/Tabs/content.d.ts +1 -1
  101. package/dist/components/Tabs/content.d.ts.map +1 -1
  102. package/dist/components/Tabs/index.d.ts +1 -1
  103. package/dist/components/Tabs/index.d.ts.map +1 -1
  104. package/dist/components/Tabs/list.d.ts +1 -1
  105. package/dist/components/Tabs/list.d.ts.map +1 -1
  106. package/dist/components/Tabs/list.js +1 -1
  107. package/dist/components/Tabs/list.js.map +1 -1
  108. package/dist/components/Tag/group.d.ts +1 -1
  109. package/dist/components/Tag/group.d.ts.map +1 -1
  110. package/dist/components/Tree/index.d.ts +2 -1
  111. package/dist/components/Tree/index.d.ts.map +1 -1
  112. package/dist/components/Tree/index.js +35 -31
  113. package/dist/components/Tree/index.js.map +1 -1
  114. package/dist/containers/Paging.d.ts +1 -1
  115. package/dist/containers/Paging.d.ts.map +1 -1
  116. package/dist/containers/ThemeProvider.d.ts +1 -1
  117. package/dist/containers/ThemeProvider.d.ts.map +1 -1
  118. package/dist/helpers/utils.d.ts +2 -1
  119. package/dist/helpers/utils.d.ts.map +1 -1
  120. package/dist/helpers/utils.js +20 -2
  121. package/dist/helpers/utils.js.map +1 -1
  122. package/dist/hooks/useAutoFocus.d.ts +1 -1
  123. package/dist/hooks/useAutoFocus.d.ts.map +1 -1
  124. package/dist/hooks/usePopover.d.ts +1 -0
  125. package/dist/hooks/usePopover.d.ts.map +1 -1
  126. package/dist/index.d.ts +1 -1
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js.map +1 -1
  129. package/dist/styles.d.ts +3 -0
  130. package/dist/styles.d.ts.map +1 -1
  131. package/dist/styles.js +49 -11
  132. package/dist/styles.js.map +1 -1
  133. package/migration-storybook.log +88 -0
  134. package/package.json +26 -20
  135. package/src/components/Breadcrumbs/index.tsx +1 -1
  136. package/src/components/Button/index.tsx +3 -54
  137. package/src/components/Collection/index.tsx +18 -15
  138. package/src/components/Collection/item.tsx +2 -1
  139. package/src/components/ExportModal/index.tsx +98 -0
  140. package/src/components/KeyValueTable/index.tsx +17 -11
  141. package/src/components/Menu/item.tsx +4 -4
  142. package/src/components/Notifications/notification.tsx +2 -2
  143. package/src/components/Panel/index.tsx +2 -2
  144. package/src/components/Table/body.tsx +6 -3
  145. package/src/components/Table/helpers.ts +52 -21
  146. package/src/components/Table/index.tsx +108 -75
  147. package/src/components/Table/row.tsx +12 -7
  148. package/src/components/Tabs/list.tsx +1 -1
  149. package/src/components/Tree/index.tsx +82 -75
  150. package/src/helpers/utils.ts +10 -2
  151. package/src/hooks/useAutoFocus.ts +1 -1
  152. package/src/index.tsx +1 -1
  153. package/src/mock/tableData.ts +12 -0
  154. package/src/stories/Breadcrumbs/Breadcrumbs.stories.tsx +11 -23
  155. package/src/stories/Button/Button.stories.tsx +83 -47
  156. package/src/stories/Checkbox/Checkbox.stories.tsx +19 -9
  157. package/src/stories/Collection/Collection.stories.tsx +195 -171
  158. package/src/stories/Columns/Columns.stories.tsx +38 -24
  159. package/src/stories/Comment/Comment.stories.tsx +15 -6
  160. package/src/stories/ControlGroup/ControlGroup.stories.tsx +102 -48
  161. package/src/stories/Drawer/Drawer.stories.tsx +52 -17
  162. package/src/stories/Dropdown/Dropdown.stories.tsx +184 -152
  163. package/src/stories/ExportModal/ExportModal.stories.tsx +18 -0
  164. package/src/stories/Header/Header.stories.tsx +65 -31
  165. package/src/stories/Icon/Icon.stories.tsx +139 -133
  166. package/src/stories/Input/Input.stories.tsx +68 -31
  167. package/src/stories/KeyValueTable/KeyValueTable.stories.tsx +143 -118
  168. package/src/stories/Menu/Menu.stories.tsx +56 -20
  169. package/src/stories/Message/Message.stories.tsx +71 -37
  170. package/src/stories/Modal/Modal.stories.tsx +28 -8
  171. package/src/stories/MultiSelect/MultiSelect.stories.tsx +66 -35
  172. package/src/stories/Navbar/Navbar.stories.tsx +15 -5
  173. package/src/stories/Notifications/Interactive.stories.tsx +40 -28
  174. package/src/stories/Notifications/Notification.stories.tsx +55 -41
  175. package/src/stories/Notifications/Notifications.stories.tsx +45 -29
  176. package/src/stories/Paging/Paging.stories.tsx +206 -177
  177. package/src/stories/Panel/Panel.stories.tsx +238 -168
  178. package/src/stories/Paragraph/Paragraph.stories.tsx +66 -31
  179. package/src/stories/Popover/Popover.stories.tsx +62 -40
  180. package/src/stories/RadioGroup/RadioGroup.stories.tsx +41 -19
  181. package/src/stories/Sidebar/Sidebar.stories.tsx +29 -10
  182. package/src/stories/Spacer/Spacer.stories.tsx +13 -5
  183. package/src/stories/Spinner/Spinner.stories.tsx +26 -12
  184. package/src/stories/Table/Table.stories.tsx +200 -144
  185. package/src/stories/Table/Tests.stories.tsx +9 -0
  186. package/src/stories/Tabs/Tabs.stories.tsx +82 -46
  187. package/src/stories/Tag/Tag.stories.tsx +56 -37
  188. package/src/stories/Tag/TagGroup.stories.tsx +297 -0
  189. package/src/stories/TextArea/TextArea.stories.tsx +82 -40
  190. package/src/stories/Tree/Tree.stories.tsx +84 -22
  191. package/src/stories/utils.ts +22 -1
  192. package/src/styles.ts +55 -2
  193. package/tests.json +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qoretechnologies/reqore",
3
- "version": "0.36.0",
3
+ "version": "0.36.1",
4
4
  "description": "ReQore is a highly theme-able and modular UI library for React",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,9 +11,9 @@
11
11
  "build": "./node_modules/typescript/bin/tsc --project tsconfig.prod.json",
12
12
  "build:test": "./node_modules/typescript/bin/tsc --noEmit",
13
13
  "build:test:prod": "./node_modules/typescript/bin/tsc --project tsconfig.prod.json --noEmit",
14
- "storybook": "start-storybook -p 6007 --no-dll",
14
+ "storybook": "storybook dev -p 6007",
15
15
  "init-storybook": "yarn test:ci && yarn storybook",
16
- "build-storybook": "build-storybook"
16
+ "build-storybook": "storybook build"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "react"
27
27
  ],
28
28
  "pre-push": [
29
- "build:test",
29
+ "build:test:prod",
30
30
  "test"
31
31
  ],
32
32
  "author": "Qore Technologies",
@@ -40,18 +40,21 @@
40
40
  "@babel/preset-env": "^7.12.11",
41
41
  "@babel/preset-react": "^7.12.10",
42
42
  "@babel/preset-typescript": "^7.12.7",
43
- "@storybook/addon-actions": "^6.5.13",
44
- "@storybook/addon-essentials": "^6.5.13",
45
- "@storybook/addon-interactions": "^6.5.13",
46
- "@storybook/addon-jest": "^6.5.13",
47
- "@storybook/addon-links": "^6.5.13",
48
- "@storybook/addon-storyshots": "^6.5.13",
49
- "@storybook/addon-storysource": "^6.5.13",
50
- "@storybook/builder-webpack5": "^6.5.13",
51
- "@storybook/jest": "^0.0.10",
52
- "@storybook/manager-webpack5": "^6.5.13",
53
- "@storybook/react": "^6.5.13",
54
- "@storybook/testing-library": "^0.0.13",
43
+ "@storybook/addon-actions": "^7.1.1",
44
+ "@storybook/addon-essentials": "^7.1.1",
45
+ "@storybook/addon-interactions": "^7.1.1",
46
+ "@storybook/addon-links": "^7.1.1",
47
+ "@storybook/builder-webpack5": "^7.1.1",
48
+ "@storybook/jest": "^0.1.0",
49
+ "@storybook/manager-api": "^7.1.1",
50
+ "@storybook/manager-webpack5": "^6.5.16",
51
+ "@storybook/react": "^7.1.1",
52
+ "@storybook/react-webpack5": "^7.1.1",
53
+ "@storybook/test-runner": "^0.9.4",
54
+ "@storybook/testing-library": "^0.2.0",
55
+ "@storybook/testing-react": "^2.0.1",
56
+ "@storybook/theming": "^7.1.1",
57
+ "@storybook/types": "^7.1.1",
55
58
  "@testing-library/jest-dom": "^5.16.5",
56
59
  "@testing-library/react": "^13.4.0",
57
60
  "@types/jest": "^26.0.19",
@@ -61,7 +64,7 @@
61
64
  "@types/react-dom": "^18.0.11",
62
65
  "babel-jest": "^26.6.3",
63
66
  "babel-loader": "^8.2.2",
64
- "chromatic": "^6.3.3",
67
+ "chromatic": "^6.20.0",
65
68
  "jest": "^29.4.3",
66
69
  "jest-environment-jsdom": "^29.4.3",
67
70
  "jest-github-actions-reporter": "^1.0.2",
@@ -72,8 +75,7 @@
72
75
  "react-dom": "^18.2.0",
73
76
  "react-intersection-observer": "^9.4.2",
74
77
  "react-test-renderer": "^18.2.0",
75
- "storybook-addon-outline": "^1.4.2",
76
- "storybook-dark-mode": "^1.1.2",
78
+ "storybook": "^7.1.1",
77
79
  "ts-jest": "^29.0.5",
78
80
  "ts-node": "^9.1.1",
79
81
  "typescript": "^4.7.3",
@@ -101,6 +103,10 @@
101
103
  "shortid": "^2.2.16",
102
104
  "styled-components": "^5.3.6",
103
105
  "thenby": "^1.3.4",
104
- "use-context-selector": "^1.4.1"
106
+ "use-context-selector": "^1.4.1",
107
+ "yaml": "^2.3.1"
108
+ },
109
+ "resolutions": {
110
+ "jackspeak": "2.1.1"
105
111
  }
106
112
  }
@@ -199,7 +199,7 @@ const ReqoreBreadcrumbs: React.FC<IReqoreBreadcrumbsProps> = ({
199
199
  {...props}
200
200
  icon={icon}
201
201
  as={as}
202
- onClick={(_itemId, event) => {
202
+ onClick={(event) => {
203
203
  props?.onClick?.(event);
204
204
  }}
205
205
  tooltip={tooltip}
@@ -23,6 +23,9 @@ import {
23
23
  InactiveIconScale,
24
24
  ReadOnlyElement,
25
25
  ScaleIconOnHover,
26
+ StyledActiveContent,
27
+ StyledInActiveContent,
28
+ StyledInvisibleContent,
26
29
  } from '../../styles';
27
30
  import {
28
31
  IReqoreDisabled,
@@ -37,7 +40,6 @@ import {
37
40
  IReqoreEffect,
38
41
  ReqoreTextEffect,
39
42
  StyledEffect,
40
- StyledTextEffect,
41
43
  TReqoreEffectColor,
42
44
  TReqoreHexColor,
43
45
  } from '../Effect';
@@ -105,59 +107,6 @@ export const StyledAnimatedTextWrapper = styled.span`
105
107
  align-items: ${({ textAlign }) => alignToFlexAlign(textAlign)};
106
108
  `;
107
109
 
108
- export const StyledActiveContent = styled(StyledTextEffect)`
109
- position: absolute;
110
- transform: translateY(-150%);
111
- opacity: 0;
112
- transition: all 0.2s ease-out;
113
- filter: blur(10px);
114
-
115
- ${({ wrap }) =>
116
- !wrap
117
- ? css`
118
- overflow: hidden;
119
- text-overflow: ellipsis;
120
- white-space: nowrap;
121
- width: 100%;
122
- `
123
- : css`
124
- word-break: break-word;
125
- `}
126
- `;
127
-
128
- export const StyledInActiveContent = styled(StyledTextEffect)`
129
- position: absolute;
130
- transform: translateY(0);
131
- transition: all 0.2s ease-out;
132
-
133
- ${({ wrap }) =>
134
- !wrap
135
- ? css`
136
- overflow: hidden;
137
- text-overflow: ellipsis;
138
- white-space: nowrap;
139
- width: 100%;
140
- `
141
- : css`
142
- word-break: break-word;
143
- `}
144
- `;
145
-
146
- export const StyledInvisibleContent = styled(StyledTextEffect)`
147
- visibility: hidden;
148
- position: relative;
149
- overflow: hidden;
150
-
151
- ${({ wrap }) =>
152
- !wrap
153
- ? css`
154
- white-space: nowrap;
155
- `
156
- : css`
157
- word-break: break-word;
158
- `}
159
- `;
160
-
161
110
  export const StyledButton = styled(StyledEffect)<IReqoreButtonStyle>`
162
111
  display: flex;
163
112
  flex-flow: column;
@@ -48,7 +48,7 @@ export interface IReqoreCollectionProps extends IReqorePanelProps, IReqoreColumn
48
48
  searchInput?: React.ReactNode
49
49
  ) => React.ReactNode;
50
50
 
51
- onQueryChange?: (query: string) => void;
51
+ onQueryChange?: (query: string | number) => void;
52
52
 
53
53
  emptyMessage?: string;
54
54
  sortButtonTooltip?: (sort?: 'asc' | 'desc') => string;
@@ -88,8 +88,10 @@ export const ReqoreCollection = ({
88
88
  maxItemHeight,
89
89
  filterable,
90
90
  inputInTitle = true,
91
+
91
92
  sortable,
92
93
  zoomable,
94
+
93
95
  defaultZoom,
94
96
  showSelectedFirst,
95
97
  inputProps,
@@ -132,6 +134,7 @@ export const ReqoreCollection = ({
132
134
  const [contentRef, setContentRef] = useState<HTMLDivElement>(undefined);
133
135
  const isMobile = useReqoreProperty('isMobile');
134
136
  const [zoom, setZoom] = useState<number>(defaultZoom || sizeToZoom.normal);
137
+
135
138
  const { query, setQuery, preQuery, setPreQuery } = useQueryWithDelay(
136
139
  defaultQuery,
137
140
  searchDelay,
@@ -199,39 +202,39 @@ export const ReqoreCollection = ({
199
202
 
200
203
  const toolbarGroup: IReqorePanelAction = {
201
204
  responsive: false,
202
- fluid: isMobile,
203
- group: [
205
+ icon: 'MoreLine',
206
+ className: 'reqore-collection-more',
207
+ actions: [
204
208
  {
205
209
  icon: _showAs === 'grid' ? 'ListUnordered' : 'GridLine',
206
210
  onClick: () => setShowAs(_showAs === 'grid' ? 'list' : 'grid'),
207
211
  tooltip: displayButtonTooltip(_showAs),
212
+ label: displayButtonTooltip(_showAs),
208
213
  disabled: !size(filteredItems),
209
- textAlign: 'center',
210
- fixed: !isMobile,
211
214
  ...displayButtonProps,
212
215
  },
213
216
  ],
214
217
  };
215
218
 
216
- if (zoomable) {
217
- actions.push({
218
- fluid: false,
219
- group: getZoomActions('reqore-collection', zoom, setZoom),
220
- });
221
- }
222
-
223
219
  if (sortable) {
224
- toolbarGroup.group.push({
220
+ toolbarGroup.actions.push({
225
221
  icon: sort === 'desc' ? 'SortDesc' : 'SortAsc',
226
222
  onClick: () => setSort(sort === 'desc' ? 'asc' : 'desc'),
227
223
  tooltip: sortButtonTooltip(sort),
224
+ label: sortButtonTooltip(sort),
228
225
  disabled: !size(filteredItems),
229
- textAlign: 'center',
230
- fixed: !isMobile,
231
226
  ...sortButtonProps,
232
227
  });
233
228
  }
234
229
 
230
+ if (zoomable) {
231
+ toolbarGroup.actions = [
232
+ ...toolbarGroup.actions,
233
+ { divider: true, line: true },
234
+ ...getZoomActions('reqore-collection', zoom, setZoom, true),
235
+ ];
236
+ }
237
+
235
238
  if (filterable && inputInTitle) {
236
239
  actions = [
237
240
  ...actions,
@@ -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
+ };
@@ -3,12 +3,7 @@ import { useMemo } from 'react';
3
3
  import { TReqoreIntent } from '../../constants/theme';
4
4
  import { IReqoreIconName } from '../../types/icons';
5
5
  import { IReqorePanelProps } from '../Panel';
6
- import ReqoreTable, {
7
- IReqoreTableColumn,
8
- IReqoreTableProps,
9
- IReqoreTableRowData,
10
- TReqoreTableColumnContent,
11
- } from '../Table';
6
+ import ReqoreTable, { IReqoreTableColumn, IReqoreTableProps, IReqoreTableRowData } from '../Table';
12
7
  import { IReqoreTableValueProps, ReqoreTableValue } from '../Table/value';
13
8
 
14
9
  export type TReqoreKeyValueTablePrimitiveValue = string | number | boolean | null | undefined;
@@ -19,7 +14,20 @@ export type TReqoreKeyValueTableValue =
19
14
 
20
15
  export interface IReqoreKeyValueTableProps
21
16
  extends IReqorePanelProps,
22
- Pick<IReqoreTableProps, 'striped' | 'width' | 'height' | 'fill'> {
17
+ Pick<
18
+ IReqoreTableProps,
19
+ | 'striped'
20
+ | 'width'
21
+ | 'height'
22
+ | 'fill'
23
+ | 'filterable'
24
+ | 'filter'
25
+ | 'onFilterChange'
26
+ | 'filterProps'
27
+ | 'zoomable'
28
+ | 'wrapperSize'
29
+ | 'paging'
30
+ > {
23
31
  data: { [key: string | number]: TReqoreKeyValueTableValue };
24
32
 
25
33
  keyLabel?: string;
@@ -36,10 +44,8 @@ export interface IReqoreKeyValueTableProps
36
44
 
37
45
  valueRenderer?: (
38
46
  data: IReqoreTableRowData,
39
- defaultComponent?: ({
40
- value,
41
- }: IReqoreTableValueProps) => TReqoreTableColumnContent | JSX.Element
42
- ) => JSX.Element;
47
+ defaultComponent?: ({ value }: IReqoreTableValueProps) => any
48
+ ) => any;
43
49
  }
44
50
 
45
51
  export const ReqoreKeyValueTable = ({
@@ -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}
@@ -236,7 +236,7 @@ const ReqoreNotification = forwardRef<HTMLDivElement, IReqoreNotificationProps>(
236
236
  onFinish,
237
237
  flat,
238
238
  minimal,
239
- opaque,
239
+ opaque = true,
240
240
  size = 'normal',
241
241
  customTheme,
242
242
  },
@@ -287,7 +287,7 @@ const ReqoreNotification = forwardRef<HTMLDivElement, IReqoreNotificationProps>(
287
287
  hasShadow
288
288
  timeout={duration}
289
289
  clickable={!!onClick}
290
- onClick={onClick}
290
+ onClick={() => onClick?.()}
291
291
  flat={flat}
292
292
  minimal={minimal}
293
293
  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
  );
@@ -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
 
@@ -73,13 +74,15 @@ const ReqoreTableBody = forwardRef<HTMLDivElement, IReqoreTableSectionBodyProps>
73
74
  [size, rest.flat]
74
75
  );
75
76
 
77
+ const itemCount = useMemo(() => count(data), [data]);
78
+
76
79
  return (
77
80
  <StyledList
78
81
  outerRef={targetRef}
79
- itemCount={data.length}
82
+ itemCount={itemCount}
80
83
  // If the defined height is less than the count of items' height
81
84
  // use that height instead
82
- height={height > data.length * rowHeight ? data.length * rowHeight : height}
85
+ height={height > itemCount * rowHeight ? itemCount * rowHeight : height}
83
86
  className='reqore-table-body'
84
87
  itemSize={rest.flat ? TABLE_SIZE_TO_PX[size] : TABLE_SIZE_TO_PX[size] + 1}
85
88
  itemData={{
@@ -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
+ };