@oliasoft-open-source/react-ui-library 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +125 -0
  3. package/.gitlab-ci.yml +45 -0
  4. package/.husky/pre-commit +4 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +4 -0
  7. package/.storybook/main.js +36 -0
  8. package/.storybook/preview.js +40 -0
  9. package/.storybook/storybook.less +8 -0
  10. package/LICENSE +21 -0
  11. package/README.md +5 -0
  12. package/babel.config.js +31 -0
  13. package/index.js +76 -0
  14. package/jest.config.js +9 -0
  15. package/package.json +136 -0
  16. package/src/components/accordion/accordion.jsx +132 -0
  17. package/src/components/accordion/accordion.module.less +66 -0
  18. package/src/components/accordion/accordion.stories.jsx +171 -0
  19. package/src/components/accordion/chevron/chevron.jsx +12 -0
  20. package/src/components/accordion/chevron/chevron.module.less +12 -0
  21. package/src/components/accordion/helpers/accordion-with-default-toggle.jsx +106 -0
  22. package/src/components/accordion/helpers/accordion-with-default-toggle.module.less +24 -0
  23. package/src/components/actions/actions.jsx +129 -0
  24. package/src/components/actions/actions.module.less +44 -0
  25. package/src/components/actions/actions.shape.js +32 -0
  26. package/src/components/actions/actions.stories.jsx +79 -0
  27. package/src/components/badge/badge.jsx +58 -0
  28. package/src/components/badge/badge.module.less +55 -0
  29. package/src/components/badge/badge.stories.jsx +31 -0
  30. package/src/components/breadcrumb/breadcrumb.jsx +49 -0
  31. package/src/components/breadcrumb/breadcrumb.module.less +39 -0
  32. package/src/components/breadcrumb/breadcrumb.stories.jsx +45 -0
  33. package/src/components/breadcrumb/link.jsx +31 -0
  34. package/src/components/button/button.jsx +156 -0
  35. package/src/components/button/button.module.less +300 -0
  36. package/src/components/button/button.stories.jsx +74 -0
  37. package/src/components/button-group/button-group.jsx +140 -0
  38. package/src/components/button-group/button-group.module.less +24 -0
  39. package/src/components/button-group/button-group.stories-data.jsx +67 -0
  40. package/src/components/button-group/button-group.stories.jsx +63 -0
  41. package/src/components/buttons-and-links.stories.mdx +55 -0
  42. package/src/components/card/card.jsx +51 -0
  43. package/src/components/card/card.module.less +48 -0
  44. package/src/components/card/card.stories.jsx +39 -0
  45. package/src/components/check-box/check-box.jsx +92 -0
  46. package/src/components/check-box/check-box.module.less +101 -0
  47. package/src/components/check-box/check-box.stories.jsx +27 -0
  48. package/src/components/color/color.stories-data.jsx +71 -0
  49. package/src/components/color/color.stories.mdx +37 -0
  50. package/src/components/dialog/dialog.jsx +64 -0
  51. package/src/components/dialog/dialog.module.less +76 -0
  52. package/src/components/divider/divider.jsx +40 -0
  53. package/src/components/divider/divider.module.less +28 -0
  54. package/src/components/divider/divider.stories.jsx +50 -0
  55. package/src/components/drawer/drawer-tabs.jsx +43 -0
  56. package/src/components/drawer/drawer.jsx +150 -0
  57. package/src/components/drawer/drawer.module.less +167 -0
  58. package/src/components/drawer/drawer.stories.jsx +156 -0
  59. package/src/components/empty/empty.jsx +52 -0
  60. package/src/components/empty/empty.module.less +17 -0
  61. package/src/components/empty/empty.stories.jsx +26 -0
  62. package/src/components/file-input/file-input.jsx +101 -0
  63. package/src/components/file-input/file-input.module.less +3 -0
  64. package/src/components/file-input/file-input.stories.jsx +109 -0
  65. package/src/components/form/field.jsx +96 -0
  66. package/src/components/form/field.stories.jsx +101 -0
  67. package/src/components/form/form.module.less +30 -0
  68. package/src/components/form/form.stories.jsx +191 -0
  69. package/src/components/heading/heading.jsx +105 -0
  70. package/src/components/heading/heading.module.less +59 -0
  71. package/src/components/heading/heading.stories.jsx +60 -0
  72. package/src/components/icon/deprecated-icon.jsx +97 -0
  73. package/src/components/icon/icon.jsx +71 -0
  74. package/src/components/icon/icon.module.less +33 -0
  75. package/src/components/icon/icon.stories.jsx +37 -0
  76. package/src/components/icon/icons.example.module.less +4 -0
  77. package/src/components/input/input.jsx +167 -0
  78. package/src/components/input/input.module.less +94 -0
  79. package/src/components/input/input.stories.jsx +28 -0
  80. package/src/components/input-group/input-group-addon/input-group-addon.jsx +36 -0
  81. package/src/components/input-group/input-group-addon/input-group-addon.module.less +31 -0
  82. package/src/components/input-group/input-group.jsx +51 -0
  83. package/src/components/input-group/input-group.module.less +10 -0
  84. package/src/components/input-group/input-group.stories.jsx +77 -0
  85. package/src/components/input-validation.stories.mdx +61 -0
  86. package/src/components/inputs.stories.mdx +201 -0
  87. package/src/components/label/label.jsx +115 -0
  88. package/src/components/label/label.module.less +43 -0
  89. package/src/components/label/label.stories.jsx +60 -0
  90. package/src/components/layout/column/column.jsx +85 -0
  91. package/src/components/layout/column/styles.js +45 -0
  92. package/src/components/layout/column.stories.jsx +60 -0
  93. package/src/components/layout/examples/afe.stories.jsx +180 -0
  94. package/src/components/layout/examples/blowout.stories.jsx +68 -0
  95. package/src/components/layout/examples/casing-loads.stories.jsx +297 -0
  96. package/src/components/layout/examples/formation.stories.jsx +110 -0
  97. package/src/components/layout/examples/projects.stories.jsx +108 -0
  98. package/src/components/layout/examples/reservoirs.stories.jsx +211 -0
  99. package/src/components/layout/examples/site.stories.jsx +263 -0
  100. package/src/components/layout/flex/flex.jsx +48 -0
  101. package/src/components/layout/flex/flex.stories.jsx +54 -0
  102. package/src/components/layout/form-row/form-row.jsx +15 -0
  103. package/src/components/layout/form-row/form-row.module.less +11 -0
  104. package/src/components/layout/grid/grid.jsx +62 -0
  105. package/src/components/layout/grid/grid.stories.jsx +65 -0
  106. package/src/components/layout/page/page.jsx +42 -0
  107. package/src/components/layout/page/page.module.less +27 -0
  108. package/src/components/layout/page.stories.jsx +93 -0
  109. package/src/components/layout/placeholder.jsx +2 -0
  110. package/src/components/layout/print-header/print-header.jsx +22 -0
  111. package/src/components/layout/print-header/print-header.module.less +9 -0
  112. package/src/components/layout/row/row.jsx +75 -0
  113. package/src/components/layout/row/row.module.less +7 -0
  114. package/src/components/layout/spacer/spacer.jsx +26 -0
  115. package/src/components/layout/spacer/spacer.stories.jsx +50 -0
  116. package/src/components/layout-forms.stories.mdx +104 -0
  117. package/src/components/layout-general.stories.mdx +215 -0
  118. package/src/components/list/list-row/item-content.jsx +15 -0
  119. package/src/components/list/list-row/label.jsx +11 -0
  120. package/src/components/list/list-row/list-heading.jsx +52 -0
  121. package/src/components/list/list-row/list-row.jsx +128 -0
  122. package/src/components/list/list-row/list-subheading.jsx +72 -0
  123. package/src/components/list/list-row/meta-content.jsx +24 -0
  124. package/src/components/list/list-row/meta-count.jsx +10 -0
  125. package/src/components/list/list-row/name.jsx +45 -0
  126. package/src/components/list/list.jsx +276 -0
  127. package/src/components/list/list.module.less +256 -0
  128. package/src/components/list/list.stories-data.jsx +287 -0
  129. package/src/components/list/list.stories.jsx +458 -0
  130. package/src/components/list/toggle-narrow.jsx +13 -0
  131. package/src/components/loader/loader.jsx +63 -0
  132. package/src/components/loader/loader.module.less +63 -0
  133. package/src/components/loader/loader.stories.jsx +155 -0
  134. package/src/components/menu/index.js +7 -0
  135. package/src/components/menu/layer/divider.jsx +4 -0
  136. package/src/components/menu/layer/heading.jsx +15 -0
  137. package/src/components/menu/layer/layer.jsx +82 -0
  138. package/src/components/menu/layer/option.jsx +77 -0
  139. package/src/components/menu/layer/path.js +44 -0
  140. package/src/components/menu/layer/placementOptions.js +6 -0
  141. package/src/components/menu/layer/section.jsx +66 -0
  142. package/src/components/menu/menu.jsx +359 -0
  143. package/src/components/menu/menu.module.less +241 -0
  144. package/src/components/menu/menu.stories-data.jsx +168 -0
  145. package/src/components/menu/menu.stories.jsx +126 -0
  146. package/src/components/menu/menu.test.js +58 -0
  147. package/src/components/menu/trigger/button.jsx +50 -0
  148. package/src/components/menu/trigger/component.jsx +14 -0
  149. package/src/components/menu/trigger/text.jsx +25 -0
  150. package/src/components/menu/trigger/trigger.jsx +86 -0
  151. package/src/components/message/dismiss.jsx +26 -0
  152. package/src/components/message/message.jsx +137 -0
  153. package/src/components/message/message.module.less +114 -0
  154. package/src/components/message/message.stories.jsx +84 -0
  155. package/src/components/modal/modal.jsx +50 -0
  156. package/src/components/modal/modal.module.less +35 -0
  157. package/src/components/modal/modal.stories.jsx +159 -0
  158. package/src/components/option-dropdown/heading.jsx +6 -0
  159. package/src/components/option-dropdown/layer.jsx +81 -0
  160. package/src/components/option-dropdown/option-dropdown.jsx +53 -0
  161. package/src/components/option-dropdown/option-dropdown.module.less +50 -0
  162. package/src/components/option-dropdown/option-dropdown.stories.jsx +35 -0
  163. package/src/components/option-dropdown/option.jsx +13 -0
  164. package/src/components/pagination/pagination.jsx +139 -0
  165. package/src/components/pagination/pagination.module.less +11 -0
  166. package/src/components/pagination/pagination.stories.jsx +78 -0
  167. package/src/components/pagination/pagination.test.js +92 -0
  168. package/src/components/pagination/pagination.viewdata.js +66 -0
  169. package/src/components/pop-confirm/content.jsx +25 -0
  170. package/src/components/pop-confirm/pop-confirm.jsx +61 -0
  171. package/src/components/pop-confirm/pop-confirm.module.less +18 -0
  172. package/src/components/pop-confirm/pop-confirm.stories.jsx +53 -0
  173. package/src/components/popover/popover.jsx +112 -0
  174. package/src/components/popover/popover.module.less +22 -0
  175. package/src/components/popover/popover.stories.jsx +59 -0
  176. package/src/components/portal/portal.jsx +16 -0
  177. package/src/components/portal/portal.stories.jsx +69 -0
  178. package/src/components/progress-bar/progress-bar.jsx +64 -0
  179. package/src/components/progress-bar/progress-bar.module.less +64 -0
  180. package/src/components/progress-bar/progress-bar.stories.jsx +23 -0
  181. package/src/components/radio-button/radio-button.jsx +139 -0
  182. package/src/components/radio-button/radio-button.module.less +135 -0
  183. package/src/components/radio-button/radio-button.stories.jsx +37 -0
  184. package/src/components/radio-button/radio-input.jsx +52 -0
  185. package/src/components/select/custom-select/custom-select.jsx +440 -0
  186. package/src/components/select/custom-select/custom-select.module.less +123 -0
  187. package/src/components/select/custom-select/custom-select.reducer.js +157 -0
  188. package/src/components/select/custom-select/layer/heading.jsx +13 -0
  189. package/src/components/select/custom-select/layer/layer.jsx +73 -0
  190. package/src/components/select/custom-select/layer/option.jsx +54 -0
  191. package/src/components/select/custom-select/layer/placementOptions.js +7 -0
  192. package/src/components/select/custom-select/layer/section.jsx +35 -0
  193. package/src/components/select/custom-select/trigger/input.jsx +100 -0
  194. package/src/components/select/custom-select/trigger/trigger.jsx +155 -0
  195. package/src/components/select/custom-select/trigger/trigger.module.less +289 -0
  196. package/src/components/select/native-select/native-select.jsx +198 -0
  197. package/src/components/select/native-select/native-select.module.less +107 -0
  198. package/src/components/select/select.input.js +146 -0
  199. package/src/components/select/select.jsx +207 -0
  200. package/src/components/select/select.stories-data.jsx +92 -0
  201. package/src/components/select/select.stories.jsx +135 -0
  202. package/src/components/select/select.test.js +519 -0
  203. package/src/components/side-bar/container.module.less +29 -0
  204. package/src/components/side-bar/link.jsx +83 -0
  205. package/src/components/side-bar/sections.jsx +23 -0
  206. package/src/components/side-bar/side-bar.jsx +102 -0
  207. package/src/components/side-bar/side-bar.module.less +137 -0
  208. package/src/components/side-bar/side-bar.stories.jsx +101 -0
  209. package/src/components/slider/rc-slider.less +47 -0
  210. package/src/components/slider/slider-tooltip.jsx +20 -0
  211. package/src/components/slider/slider.jsx +233 -0
  212. package/src/components/slider/slider.module.less +40 -0
  213. package/src/components/slider/slider.stories.jsx +110 -0
  214. package/src/components/spinner/spinner.jsx +37 -0
  215. package/src/components/spinner/spinner.module.less +115 -0
  216. package/src/components/spinner/spinner.stories.jsx +24 -0
  217. package/src/components/table/cell/cell.jsx +614 -0
  218. package/src/components/table/cell/cell.module.less +152 -0
  219. package/src/components/table/footer/footer.jsx +66 -0
  220. package/src/components/table/footer/footer.module.less +14 -0
  221. package/src/components/table/helper.js +64 -0
  222. package/src/components/table/helper.test.js +166 -0
  223. package/src/components/table/icon/icon.module.less +31 -0
  224. package/src/components/table/row/expanded-content-row.jsx +16 -0
  225. package/src/components/table/row/row.jsx +253 -0
  226. package/src/components/table/row/row.module.less +62 -0
  227. package/src/components/table/table-scroll-wrapper.jsx +48 -0
  228. package/src/components/table/table.jsx +232 -0
  229. package/src/components/table/table.module.less +145 -0
  230. package/src/components/table/table.stories-data.jsx +752 -0
  231. package/src/components/table/table.stories.jsx +814 -0
  232. package/src/components/table/table.test.js +30 -0
  233. package/src/components/table/table.variables.less +19 -0
  234. package/src/components/table/table.viewdata.js +26 -0
  235. package/src/components/table/title/title.jsx +30 -0
  236. package/src/components/table/title/title.module.less +9 -0
  237. package/src/components/tabs/content.jsx +14 -0
  238. package/src/components/tabs/label.jsx +50 -0
  239. package/src/components/tabs/tabs.jsx +191 -0
  240. package/src/components/tabs/tabs.module.less +73 -0
  241. package/src/components/tabs/tabs.stories.jsx +110 -0
  242. package/src/components/text/text.jsx +64 -0
  243. package/src/components/text/text.module.less +45 -0
  244. package/src/components/text/text.stories.jsx +31 -0
  245. package/src/components/text-link/text-link.jsx +23 -0
  246. package/src/components/text-link/text-link.stories.jsx +20 -0
  247. package/src/components/textarea/textarea.jsx +126 -0
  248. package/src/components/textarea/textarea.module.less +55 -0
  249. package/src/components/textarea/textarea.stories.jsx +26 -0
  250. package/src/components/toaster/toaster.jsx +39 -0
  251. package/src/components/toaster/toaster.less +17 -0
  252. package/src/components/toaster/toaster.stories.jsx +116 -0
  253. package/src/components/toggle/toggle.jsx +65 -0
  254. package/src/components/toggle/toggle.module.less +139 -0
  255. package/src/components/toggle/toggle.stories.jsx +26 -0
  256. package/src/components/tooltip/tooltip-layer.jsx +72 -0
  257. package/src/components/tooltip/tooltip.jsx +108 -0
  258. package/src/components/tooltip/tooltip.module.less +28 -0
  259. package/src/components/tooltip/tooltip.stories.jsx +71 -0
  260. package/src/components/top-bar/element/element.jsx +72 -0
  261. package/src/components/top-bar/element/link.jsx +29 -0
  262. package/src/components/top-bar/title.jsx +24 -0
  263. package/src/components/top-bar/top-bar.jsx +79 -0
  264. package/src/components/top-bar/top-bar.module.less +191 -0
  265. package/src/components/top-bar/top-bar.stories.jsx +137 -0
  266. package/src/components/top-bar/warning.jsx +6 -0
  267. package/src/components/tree/tree-item.jsx +79 -0
  268. package/src/components/tree/tree-placeholder.jsx +6 -0
  269. package/src/components/tree/tree.jsx +129 -0
  270. package/src/components/tree/tree.module.less +33 -0
  271. package/src/components/tree/tree.stories-data.jsx +89 -0
  272. package/src/components/tree/tree.stories.jsx +106 -0
  273. package/src/docs/components/page/page.jsx +16 -0
  274. package/src/docs/config/config.js +1 -0
  275. package/src/docs/html/favicon.png +0 -0
  276. package/src/docs/html/index.html +11 -0
  277. package/src/docs/navigation/footer/footer.jsx +48 -0
  278. package/src/docs/navigation/header/header.jsx +39 -0
  279. package/src/docs/navigation/header/header.module.less +32 -0
  280. package/src/docs/navigation/routes/routes.jsx +16 -0
  281. package/src/docs/start.jsx +12 -0
  282. package/src/docs/views/main/main.jsx +209 -0
  283. package/src/docs/views/main/main.module.less +14 -0
  284. package/src/docs/views/not-found/not-found.jsx +5 -0
  285. package/src/helpers/disabled-context.js +8 -0
  286. package/src/helpers/styles.js +68 -0
  287. package/src/helpers/text.js +6 -0
  288. package/src/helpers/types.js +5 -0
  289. package/src/hooks/index.js +3 -0
  290. package/src/hooks/use-focus.js +11 -0
  291. package/src/hooks/use-keyboard-event.js +16 -0
  292. package/src/hooks/use-window-width.js +20 -0
  293. package/src/images/icons/icon-drop.png +0 -0
  294. package/src/images/icons/icon-share.png +0 -0
  295. package/src/images/icons/icons8-junction.svg +4 -0
  296. package/src/images/logo.png +0 -0
  297. package/src/images/logo.svg +13 -0
  298. package/src/images/oliasoft-logo.svg +1 -0
  299. package/src/style/colors.less +26 -0
  300. package/src/style/external.less +10 -0
  301. package/src/style/fonts/lato/Lato-Bold.woff2 +0 -0
  302. package/src/style/fonts/lato/Lato-BoldItalic.woff2 +0 -0
  303. package/src/style/fonts/lato/Lato-Italic.woff2 +0 -0
  304. package/src/style/fonts/lato/Lato-Regular.woff2 +0 -0
  305. package/src/style/fonts.less +27 -0
  306. package/src/style/global.less +51 -0
  307. package/src/style/mixins.less +67 -0
  308. package/src/style/reset/reset.less +34 -0
  309. package/src/style/shared.less +25 -0
  310. package/src/style/theme.dark.less +37 -0
  311. package/src/style/theme.default.less +74 -0
  312. package/src/style/variables.less +49 -0
  313. package/webpack/webpack.common.js +39 -0
  314. package/webpack/webpack.common.rules.js +102 -0
  315. package/webpack/webpack.dev.js +22 -0
  316. package/webpack/webpack.prod.js +23 -0
  317. package/webpack/webpack.resolve.js +22 -0
@@ -0,0 +1,814 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { FaMinus, FaPlus } from 'react-icons/fa';
3
+ import {
4
+ Table,
5
+ Card,
6
+ Heading,
7
+ Field,
8
+ Button,
9
+ Input,
10
+ Text,
11
+ Flex,
12
+ } from '../../..';
13
+ import * as storyData from './table.stories-data';
14
+
15
+ export default {
16
+ title: 'Basic/Table',
17
+ component: Table,
18
+ args: {
19
+ table: {
20
+ ...storyData.table,
21
+ },
22
+ },
23
+ };
24
+
25
+ const Template = (args) => {
26
+ return (
27
+ <Table
28
+ // eslint-disable-next-line react/jsx-props-no-spreading
29
+ {...args}
30
+ />
31
+ );
32
+ };
33
+ export const Default = Template.bind({});
34
+
35
+ export const Units = Template.bind({});
36
+ Units.args = {
37
+ table: storyData.tableUnits,
38
+ };
39
+
40
+ export const ActiveRow = Template.bind({});
41
+ ActiveRow.args = {
42
+ table: storyData.tableActiveRow,
43
+ };
44
+
45
+ export const MinimumColumnWidths = Template.bind({});
46
+ MinimumColumnWidths.args = {
47
+ table: storyData.tableColumnWidths,
48
+ };
49
+ MinimumColumnWidths.parameters = {
50
+ docs: {
51
+ description: {
52
+ story:
53
+ 'Use sparingly when certain columns cannot be below a certain width. Make sure at least one column is set to `auto` to use remaining space.',
54
+ },
55
+ },
56
+ };
57
+
58
+ export const Colspan = Template.bind({});
59
+ Colspan.args = {
60
+ table: storyData.tableColspan,
61
+ };
62
+
63
+ export const ColumnAlignment = Template.bind({});
64
+ ColumnAlignment.args = {
65
+ table: storyData.tableAlignment,
66
+ };
67
+
68
+ export const Editable = Template.bind({});
69
+ Editable.args = {
70
+ table: storyData.tableEditable,
71
+ };
72
+
73
+ export const StickyHeaders = Template.bind({});
74
+ StickyHeaders.args = {
75
+ table: storyData.tableStickyHeaders,
76
+ };
77
+
78
+ export const InfiniteScroll = Template.bind({});
79
+ InfiniteScroll.args = {
80
+ table: storyData.tableInfiniteScroll,
81
+ };
82
+
83
+ export const InfiniteScrollWithDragAndDrop = Template.bind({});
84
+ InfiniteScrollWithDragAndDrop.args = {
85
+ table: storyData.tableInfiniteScrollDnD,
86
+ };
87
+
88
+ export const Title = Template.bind({});
89
+ Title.args = {
90
+ table: storyData.tableTitle,
91
+ };
92
+
93
+ export const Filter = Template.bind({});
94
+ Filter.args = {
95
+ table: storyData.tableFilters,
96
+ };
97
+
98
+ export const Sort = Template.bind({});
99
+ Sort.args = {
100
+ table: storyData.tableSort,
101
+ };
102
+
103
+ export const Icons = Template.bind({});
104
+ Icons.args = {
105
+ table: storyData.tableIcons,
106
+ };
107
+
108
+ export const Actions = Template.bind({});
109
+ Actions.args = {
110
+ table: storyData.tableActions,
111
+ };
112
+
113
+ export const Menus = Template.bind({});
114
+ Menus.args = {
115
+ table: storyData.tableWithSubActions,
116
+ };
117
+
118
+ export const RowFocusEvent = Template.bind({});
119
+ RowFocusEvent.args = {
120
+ table: storyData.tableRowFocus,
121
+ };
122
+
123
+ export const DragAndDrop = () => {
124
+ const withDragAndDrop = {
125
+ draggable: true,
126
+ headers: [
127
+ {
128
+ cells: [
129
+ { value: 'Name' },
130
+ { value: 'Weight (kg)' },
131
+ { value: 'Energy (kcal / 100g)' },
132
+ { value: 'Origin' },
133
+ ],
134
+ },
135
+ ],
136
+ rows: [
137
+ {
138
+ noDrag: true,
139
+ cells: [
140
+ { value: 'Undraggable' },
141
+ { value: 100 },
142
+ { value: 361 },
143
+ { value: 'Vietnam' },
144
+ ],
145
+ },
146
+ {
147
+ cells: [
148
+ { value: 'Buckwheat' },
149
+ { value: 50 },
150
+ { value: 358 },
151
+ { value: 'Poland' },
152
+ ],
153
+ },
154
+ {
155
+ cells: [
156
+ { value: 'Couscous' },
157
+ { value: 10 },
158
+ { value: 368 },
159
+ { value: 'France' },
160
+ ],
161
+ },
162
+ ],
163
+ };
164
+ const arraymove = (arr, from, to) => {
165
+ const copy = [...arr];
166
+ if (arr[to].noDrag) {
167
+ return arr;
168
+ }
169
+ copy.splice(to, 0, copy.splice(from, 1)[0]);
170
+ return copy;
171
+ };
172
+ const [rows, setRows] = useState(withDragAndDrop.rows);
173
+ const onListReorder = (reorderData) => {
174
+ const { to, from } = reorderData;
175
+ arraymove(rows, from, to);
176
+ setRows(arraymove(rows, from, to));
177
+ };
178
+ return (
179
+ <Table table={{ ...withDragAndDrop, rows }} onListReorder={onListReorder} />
180
+ );
181
+ };
182
+
183
+ export const ChildComponent = Template.bind({});
184
+ ChildComponent.args = {
185
+ table: storyData.tableChildComponent,
186
+ };
187
+
188
+ export const JSXContent = Template.bind({});
189
+ JSXContent.args = {
190
+ table: storyData.tableJsxContent,
191
+ };
192
+
193
+ export const Footer = Template.bind({});
194
+ Footer.args = {
195
+ table: storyData.tableFooter,
196
+ };
197
+
198
+ export const InCard = () => (
199
+ <Card heading={<Heading>Card heading</Heading>} padding={false}>
200
+ <Table table={{ ...storyData.table, bordered: false }} />
201
+ </Card>
202
+ );
203
+ InCard.parameters = {
204
+ docs: { source: { type: 'dynamic' } },
205
+ };
206
+
207
+ export const NotStriped = Template.bind({});
208
+ NotStriped.args = {
209
+ table: {
210
+ ...storyData.table,
211
+ striped: false,
212
+ },
213
+ };
214
+ NotStriped.parameters = {
215
+ docs: {
216
+ description: {
217
+ story: '`striped: false` removes tinted background on alternative rows.',
218
+ },
219
+ },
220
+ };
221
+
222
+ export const StaticCellTooltips = Template.bind({});
223
+ StaticCellTooltips.args = {
224
+ table: storyData.tableStaticTooltips,
225
+ };
226
+
227
+ export const WordbreakLongContent = Template.bind({});
228
+ WordbreakLongContent.args = {
229
+ table: storyData.tableBreakLongContent,
230
+ };
231
+ WordbreakLongContent.parameters = {
232
+ docs: {
233
+ description: {
234
+ story:
235
+ 'Setting `breakWord: true` on a cell will allow very long text strings to break',
236
+ },
237
+ },
238
+ };
239
+
240
+ export const HelpAndLibraryIcons = Template.bind({});
241
+ HelpAndLibraryIcons.args = {
242
+ table: storyData.tableHelpLibraryIcons,
243
+ };
244
+
245
+ export const Expandable = () => {
246
+ const [expandedRow, setExpandedRow] = useState(null);
247
+ const toggleExpandedRow = (rowIndex) =>
248
+ expandedRow === rowIndex ? setExpandedRow(null) : setExpandedRow(rowIndex);
249
+ return (
250
+ <Table
251
+ table={{
252
+ ...storyData.table,
253
+ rows: storyData.table.rows.map((row, index) => ({
254
+ ...row,
255
+ onRowClick: () => toggleExpandedRow(index),
256
+ expandedContent: {
257
+ content:
258
+ expandedRow === index ? (
259
+ <div>Example expanded content</div>
260
+ ) : null,
261
+ },
262
+ })),
263
+ }}
264
+ />
265
+ );
266
+ };
267
+
268
+ export const Popover = () => {
269
+ const headings = ['Section', 'Width', 'Height'];
270
+ let units = ['', 'm', 'm'];
271
+ let data = [...Array(10).keys()].map((c, i) => [i, i * 2, i * 2]);
272
+ /*
273
+ Mock table data store (real apps should use Redux or similar)
274
+ */
275
+ const PopoverTable = () => {
276
+ const CellInputForm = ({ close, value }) => (
277
+ <>
278
+ <Field label="Input">
279
+ <Input value={value} width="100%" />
280
+ </Field>
281
+ <Flex gap>
282
+ <Button colored label="Save" onClick={() => {}} />
283
+ <Button label="Cancel" onClick={close} />
284
+ </Flex>
285
+ </>
286
+ );
287
+ const table = {
288
+ fixedWidth: '100%',
289
+ headers: [
290
+ {
291
+ cells: headings.map((h) => ({ value: h })),
292
+ },
293
+ {
294
+ cells: [
295
+ {},
296
+ {
297
+ menu: [
298
+ { label: 'm', value: 'm' },
299
+ { label: 'ft', value: 'ft' },
300
+ ],
301
+ value: units[1],
302
+ type: 'Unit',
303
+ },
304
+ {
305
+ menu: [
306
+ { label: 'm', value: 'm' },
307
+ { label: 'ft', value: 'ft' },
308
+ ],
309
+ value: units[2],
310
+ type: 'Unit',
311
+ },
312
+ ],
313
+ },
314
+ ],
315
+ rows: data.map((row, i) => {
316
+ return {
317
+ cells: [...Array(3).keys()].map((c, i) => ({
318
+ //https://stackoverflow.com/a/33352604
319
+ value: row[i],
320
+ type: 'Popover',
321
+ content: <CellInputForm value={row[i]} />,
322
+ })),
323
+ };
324
+ }),
325
+ };
326
+ return <Table table={table} />;
327
+ };
328
+ return <PopoverTable />;
329
+ };
330
+
331
+ export const SinglePopoverAtOnce = () => {
332
+ const headings = ['Section', 'Width', 'Height'];
333
+ let units = ['', 'm', 'm'];
334
+ let data = [...Array(10).keys()].map((c, i) => [i, i * 2, i * 2]);
335
+ /*
336
+ Mock table data store (real apps should use Redux or similar)
337
+ */
338
+ const SinglePopoverOpenedTable = () => {
339
+ const [isPopOverCellOpened, setIsPopOverCellOpened] = useState(false);
340
+ const CellInputForm = ({ close, value }) => {
341
+ useEffect(() => {
342
+ if (!isPopOverCellOpened) {
343
+ setIsPopOverCellOpened(true);
344
+ }
345
+ }, []);
346
+ const onClosePopOver = () => {
347
+ setIsPopOverCellOpened(false);
348
+ close();
349
+ };
350
+ return (
351
+ <>
352
+ <Field label="Input">
353
+ <Input value={value} width="100%" />
354
+ </Field>
355
+ <Flex gap>
356
+ <Button colored label="Save" onClick={onClosePopOver} />
357
+ <Button label="Cancel" onClick={onClosePopOver} />
358
+ </Flex>
359
+ </>
360
+ );
361
+ };
362
+ const table = {
363
+ headers: [
364
+ {
365
+ cells: headings.map((h) => ({ value: h })),
366
+ },
367
+ {
368
+ cells: [
369
+ {},
370
+ {
371
+ menu: [
372
+ { label: 'm', value: 'm' },
373
+ { label: 'ft', value: 'ft' },
374
+ ],
375
+ value: units[1],
376
+ type: 'Unit',
377
+ },
378
+ {
379
+ menu: [
380
+ { label: 'm', value: 'm' },
381
+ { label: 'ft', value: 'ft' },
382
+ ],
383
+ value: units[2],
384
+ type: 'Unit',
385
+ },
386
+ ],
387
+ },
388
+ ],
389
+ rows: data.map((row, i) => {
390
+ return {
391
+ cells: [...Array(3).keys()].map((c, i) => ({
392
+ //https://stackoverflow.com/a/33352604
393
+ value: row[i],
394
+ type: 'Popover',
395
+ disabled: isPopOverCellOpened,
396
+ closeOnOutsideClick: false,
397
+ content: <CellInputForm value={row[i]} />,
398
+ })),
399
+ };
400
+ }),
401
+ };
402
+ return <Table table={table} />;
403
+ };
404
+ return <SinglePopoverOpenedTable />;
405
+ };
406
+
407
+ export const Managed = () => {
408
+ /*
409
+ Mock table data store (real apps should use Redux or similar)
410
+ */
411
+ const headings = ['Section', 'Width', 'Height'];
412
+ let units = ['', 'm', 'm'];
413
+ let data = [...Array(175).keys()].map((c, i) => [i, i * 2, i * 2]);
414
+ /*
415
+ Mock table data actions (real apps should use Redux or similar)
416
+ */
417
+ const convertUnit = (fromUnit, toUnit, value) => {
418
+ return fromUnit === 'm' && toUnit === 'ft'
419
+ ? value * 3.28084
420
+ : fromUnit === 'ft' && toUnit === 'm'
421
+ ? value / 3.28084
422
+ : value;
423
+ };
424
+ const onChangeValue = (evt, rowIndex, cellIndex, render) => {
425
+ data[rowIndex][cellIndex] = evt.target.value;
426
+ render();
427
+ };
428
+ const onAddRow = (render) => {
429
+ data = data.concat([['', '', '']]);
430
+ render();
431
+ };
432
+ const onDeleteRow = (rowIndex, render) => {
433
+ data = data.filter((r, i) => i !== rowIndex);
434
+ render();
435
+ };
436
+ const onChangeUnit = (evt, columnIndex, render) => {
437
+ const fromUnit = units[columnIndex];
438
+ const toUnit = evt.target.value;
439
+ units = units.map((u, i) => (i === columnIndex ? toUnit : u));
440
+ data = data.map((r) =>
441
+ r.map((c, i) =>
442
+ i === columnIndex ? convertUnit(fromUnit, toUnit, c) : c,
443
+ ),
444
+ );
445
+ render();
446
+ };
447
+ /*
448
+ Container component manages state and configuration of table
449
+ */
450
+ const ManagedTable = () => {
451
+ const rowsPerPageOptions = [
452
+ { label: '10 / page', value: 10 },
453
+ { label: '20 / page', value: 20 },
454
+ { label: '50 / page', value: 50 },
455
+ { label: 'Show all', value: 0 },
456
+ ];
457
+ const [rowsPerPage, setRowsPerPage] = useState(10);
458
+ const [selectedPage, setSelectedPage] = useState(1);
459
+ //hack to make Storybook re-render after event handlers alter data
460
+ //only using this because example does not manage data with Redux / props
461
+ const [toggle, forceRender] = useState(false);
462
+ const render = () => {
463
+ forceRender(!toggle);
464
+ };
465
+ const goToLastPage = () => {
466
+ const lastPage = Math.ceil(data.length / rowsPerPage);
467
+ setSelectedPage(lastPage);
468
+ };
469
+ const firstVisibleRow = (selectedPage - 1) * rowsPerPage;
470
+ const lastVisibleRow =
471
+ rowsPerPage === 0 ? data.length - 1 : firstVisibleRow + rowsPerPage;
472
+ const table = {
473
+ headers: [
474
+ {
475
+ cells: headings.map((h) => ({ value: h })),
476
+ actions: [
477
+ {
478
+ primary: true,
479
+ label: 'Add',
480
+ icon: <FaPlus />,
481
+ onClick: () => {
482
+ onAddRow(render);
483
+ goToLastPage();
484
+ },
485
+ },
486
+ ],
487
+ },
488
+ {
489
+ cells: [
490
+ {},
491
+ {
492
+ options: [
493
+ { label: 'm', value: 'm' },
494
+ { label: 'ft', value: 'ft' },
495
+ ],
496
+ value: units[1],
497
+ type: 'Select',
498
+ native: true,
499
+ onChange: (evt) => onChangeUnit(evt, 1, render),
500
+ },
501
+ {
502
+ options: [
503
+ { label: 'm', value: 'm' },
504
+ { label: 'ft', value: 'ft' },
505
+ ],
506
+ value: units[2],
507
+ type: 'Select',
508
+ native: true,
509
+ onChange: (evt) => onChangeUnit(evt, 2, render),
510
+ },
511
+ ],
512
+ },
513
+ ],
514
+ rows: data.slice(firstVisibleRow, lastVisibleRow).map((row, i) => {
515
+ const rowIndex = firstVisibleRow + i;
516
+ return {
517
+ cells: [...Array(3).keys()].map((c, i) => ({
518
+ //https://stackoverflow.com/a/33352604
519
+ value: row[i],
520
+ type: 'Input',
521
+ onChange: (evt) => onChangeValue(evt, rowIndex, i, render),
522
+ })),
523
+ actions: [
524
+ {
525
+ label: 'Delete',
526
+ icon: <FaMinus />,
527
+ onClick: () => onDeleteRow(rowIndex, render),
528
+ },
529
+ ],
530
+ };
531
+ }),
532
+ footer: {
533
+ pagination: {
534
+ rowCount: data.length,
535
+ selectedPage,
536
+ rowsPerPage: {
537
+ onChange: (evt) => {
538
+ const { value } = evt.target;
539
+ setRowsPerPage(Number(value));
540
+ },
541
+ options: rowsPerPageOptions,
542
+ value: rowsPerPage,
543
+ },
544
+ onSelectPage: (evt) => setSelectedPage(evt),
545
+ small: true,
546
+ },
547
+ },
548
+ };
549
+ return <Table table={table} />;
550
+ };
551
+ return <ManagedTable />;
552
+ };
553
+
554
+ export const ManagedWithFilterAndSort = () => {
555
+ /*
556
+ Mock table data store (real apps should use Redux or similar)
557
+ */
558
+ const headings = ['Section', 'Width', 'Height'];
559
+ let keyedData = [...Array(175).keys()].map((_c, i) => ({
560
+ Section: i,
561
+ Width: i * 2,
562
+ Height: i * 2,
563
+ }));
564
+ /*
565
+ Container component manages state and configuration of table
566
+ */
567
+ const TableWithSortAndFilter = () => {
568
+ const rowsPerPageOptions = [
569
+ { label: '10 / page', value: 10 },
570
+ { label: '20 / page', value: 20 },
571
+ { label: '50 / page', value: 50 },
572
+ { label: 'Show all', value: 0 },
573
+ ];
574
+ const [rowsPerPage, setRowsPerPage] = useState(10);
575
+ const [selectedPage, setSelectedPage] = useState(1);
576
+ const [filters, setFilters] = useState({});
577
+ const [sorts, setSorts] = useState({});
578
+ useEffect(() => {
579
+ setSelectedPage(1);
580
+ }, [filters, sorts]);
581
+ const firstVisibleRow = (selectedPage - 1) * rowsPerPage;
582
+ const lastVisibleRow =
583
+ rowsPerPage === 0 ? keyedData.length - 1 : firstVisibleRow + rowsPerPage;
584
+ const filterAndSortDataRows = (dataRows, filters, sorts) =>
585
+ dataRows
586
+ .filter((row) =>
587
+ Object.keys(filters).every((key) => {
588
+ return filters[key] === ''
589
+ ? true
590
+ : row[key].toString().includes(filters[key]);
591
+ }),
592
+ )
593
+ .sort((a, b) =>
594
+ Object.entries(sorts)
595
+ .map(([key, value]) => {
596
+ switch (value) {
597
+ case 'up': {
598
+ return a[key] - b[key];
599
+ }
600
+ case 'down': {
601
+ return b[key] - a[key];
602
+ }
603
+ default:
604
+ return 0;
605
+ }
606
+ })
607
+ .reduce((a, acc) => a || acc, 0),
608
+ );
609
+ const dataHeaders = (
610
+ dataRowsKeys,
611
+ filters,
612
+ setFilters,
613
+ sorts,
614
+ setSorts,
615
+ ) => {
616
+ const dataSortCells = dataRowsKeys.map((key) => {
617
+ const sort = Object.keys(sorts).includes(key) ? sorts[key] : '';
618
+ const prettifyHeaderValue = `${key[0].toUpperCase()}${key.slice(1)}`;
619
+ return {
620
+ key,
621
+ value: prettifyHeaderValue,
622
+ hasSort: true,
623
+ sort,
624
+ onSort: () => {
625
+ const newSort = sort === '' ? 'up' : sort === 'up' ? 'down' : '';
626
+ setSorts({ ...sorts, [key]: newSort });
627
+ },
628
+ };
629
+ });
630
+ const dataFilterCells = dataRowsKeys.map((key) => {
631
+ const filterValue = Object.keys(filters).includes(key)
632
+ ? filters[key]
633
+ : '';
634
+ return {
635
+ key,
636
+ value: filterValue,
637
+ type: 'Input',
638
+ placeholder: 'Filter',
639
+ onChange: (ev) => setFilters({ ...filters, [key]: ev.target.value }),
640
+ };
641
+ });
642
+ return { dataSortCells, dataFilterCells };
643
+ };
644
+ const { dataSortCells, dataFilterCells } = dataHeaders(
645
+ headings,
646
+ filters,
647
+ setFilters,
648
+ sorts,
649
+ setSorts,
650
+ );
651
+ const filteredAndSortedData = filterAndSortDataRows(
652
+ keyedData,
653
+ filters,
654
+ sorts,
655
+ );
656
+ const dataRows = [
657
+ ...filteredAndSortedData
658
+ .slice(firstVisibleRow, lastVisibleRow)
659
+ .map((dataRow) => {
660
+ const rowsCells = Object.entries(dataRow).map(([key, value]) => ({
661
+ key,
662
+ value,
663
+ type: 'Input',
664
+ disabled: true,
665
+ }));
666
+ return {
667
+ cells: rowsCells,
668
+ };
669
+ }),
670
+ ];
671
+ const table = {
672
+ headers: [
673
+ {
674
+ cells: dataSortCells,
675
+ },
676
+ {
677
+ cells: dataFilterCells,
678
+ },
679
+ ],
680
+ rows: dataRows,
681
+ footer: {
682
+ pagination: {
683
+ rowCount: filteredAndSortedData.length,
684
+ selectedPage,
685
+ rowsPerPage: {
686
+ onChange: (evt) => {
687
+ const { value } = evt.target;
688
+ setRowsPerPage(Number(value));
689
+ },
690
+ options: rowsPerPageOptions,
691
+ value: rowsPerPage,
692
+ },
693
+ onSelectPage: (evt) => setSelectedPage(evt),
694
+ small: true,
695
+ },
696
+ },
697
+ };
698
+ return <Table table={table} />;
699
+ };
700
+ return <TableWithSortAndFilter />;
701
+ };
702
+
703
+ export const OnRowEnter = () => {
704
+ const [displayText, setDisplayText] = useState('Hover any row!');
705
+ const rows = [1, 2, 3, 4, 5].map((val) => ({
706
+ cells: [{ value: `Row ${val}` }, { value: `${val ** 2}` }],
707
+ onRowMouseEnter: () => setDisplayText(`Hovering row ${val}`),
708
+ onRowMouseLeave: () => setDisplayText('Not hovering any row...'),
709
+ }));
710
+ return (
711
+ <>
712
+ <Text>{displayText}</Text>
713
+ <Table
714
+ table={{
715
+ fixedWidth: '100%',
716
+ headers: [
717
+ {
718
+ cells: [{ value: 'Description' }, { value: 'Value' }],
719
+ onRowMouseEnter: () => setDisplayText(`Hovering header row`),
720
+ onRowMouseLeave: () => setDisplayText('Not hovering any row...'),
721
+ },
722
+ ],
723
+ rows,
724
+ }}
725
+ />
726
+ </>
727
+ );
728
+ };
729
+
730
+ export const OverflowingCells = () => (
731
+ <Table
732
+ table={{
733
+ fixedWidth: '100%',
734
+ headers: [
735
+ {
736
+ cells: [
737
+ { value: 'Name' },
738
+ { value: 'Weight (kg)' },
739
+ { value: 'Energy (kcal / 100g)' },
740
+ { value: 'Origin' },
741
+ ],
742
+ },
743
+ ],
744
+ rows: [
745
+ {
746
+ cells: [
747
+ {
748
+ breakWord: true,
749
+ value:
750
+ 'LoremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaUtenimadminimveniamquisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequatDuisauteiruredolorinreprehenderitinvoluptatevelitessecillumdoloreeullamcolaborisnisiutaliquipexeacommodoconsequatDuisauteiruredolorinreprehenderitinvoluptatevelitessecillumdoloreeufugiatnullapariaturufugiatnullapariatur',
751
+ },
752
+ {
753
+ type: 'Select',
754
+ native: true,
755
+ options: [
756
+ { label: 50, value: 50 },
757
+ { label: 100, value: 100 },
758
+ ],
759
+ value: { label: 100, value: 100 },
760
+ onChange: () => {},
761
+ disabled: true,
762
+ },
763
+ {
764
+ type: 'Select',
765
+ options: [
766
+ { label: 'Vietnam', value: 'Vietnam' },
767
+ { label: 'Other', value: 'Other' },
768
+ ],
769
+ value: { label: 'Vietnam', value: 'Vietnam' },
770
+ onChange: () => {},
771
+ error: 'Error',
772
+ },
773
+ {
774
+ value: 'Brown rice',
775
+ type: 'Input',
776
+ onChange: () => {},
777
+ testId: 'table-tbody-cell-brown-rice',
778
+ },
779
+ ],
780
+ },
781
+ {
782
+ cells: [
783
+ { value: 'Buckwheat' },
784
+ {
785
+ type: 'Select',
786
+ native: true,
787
+ options: [
788
+ { label: 50, value: 50 },
789
+ { label: 100, value: 100 },
790
+ ],
791
+ value: { label: 100, value: 100 },
792
+ onChange: () => {},
793
+ },
794
+ {
795
+ type: 'Select',
796
+ options: [
797
+ { label: 'Vietnam', value: 'Vietnam' },
798
+ { label: 'Other', value: 'Other' },
799
+ ],
800
+ value: { label: 'Vietnam', value: 'Vietnam' },
801
+ onChange: () => {},
802
+ },
803
+ {
804
+ value: 'Brown rice',
805
+ type: 'Input',
806
+ onChange: () => {},
807
+ testId: 'table-tbody-cell-brown-rice',
808
+ },
809
+ ],
810
+ },
811
+ ],
812
+ }}
813
+ />
814
+ );