@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,94 @@
1
+ @import '../../style/variables.less';
2
+ @import '../../style/mixins.less';
3
+
4
+ .input {
5
+ margin: 0;
6
+ outline: 0;
7
+ text-align: left;
8
+ font-family: @default_font;
9
+ padding: @input_padding_y @input_padding_x;
10
+ background: var(--color-background-input);
11
+ border: 1px solid var(--color-border);
12
+ color: var(--color-text);
13
+ border-radius: @input_border_radius;
14
+ transition: box-shadow 0.1s ease, border-color 0.1s ease;
15
+ box-shadow: none;
16
+ height: @input_height;
17
+ width: 100%;
18
+ font-weight: 400;
19
+ font-style: normal;
20
+ position: relative;
21
+
22
+ &::placeholder {
23
+ color: var(--color-text-faint);
24
+ }
25
+
26
+ &.isInTable {
27
+ .inputInTable();
28
+ }
29
+
30
+ &:hover,
31
+ &:focus {
32
+ z-index: 1;
33
+ }
34
+
35
+ &:hover {
36
+ border-color: var(--color-border-hover);
37
+ }
38
+
39
+ &:focus {
40
+ .inputFocus();
41
+ }
42
+
43
+ &.small {
44
+ font-size: @input_font_size_small;
45
+ height: @input_height_small;
46
+ padding: 0 @input_padding_small_x;
47
+ line-height: @input_height_small;
48
+ }
49
+
50
+ &.error {
51
+ .inputError();
52
+ }
53
+
54
+ &.warning {
55
+ .inputWarning();
56
+ }
57
+
58
+ &[disabled] {
59
+ .inputDisabled();
60
+ }
61
+
62
+ &.right {
63
+ text-align: right;
64
+ }
65
+ }
66
+
67
+ .groupOrderFirst,
68
+ .groupOrderMiddle,
69
+ .groupOrderLast {
70
+ flex: 1;
71
+
72
+ .input:hover,
73
+ .input:focus {
74
+ z-index: 2;
75
+ }
76
+ }
77
+
78
+ .groupOrderFirst,
79
+ .groupOrderMiddle {
80
+ margin-right: -1px;
81
+
82
+ .input {
83
+ border-top-right-radius: 0 !important;
84
+ border-bottom-right-radius: 0 !important;
85
+ }
86
+ }
87
+
88
+ .groupOrderLast,
89
+ .groupOrderMiddle {
90
+ .input {
91
+ border-top-left-radius: 0 !important;
92
+ border-bottom-left-radius: 0 !important;
93
+ }
94
+ }
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { useArgs } from '@storybook/addons';
3
+ import { Input } from '../../..';
4
+
5
+ export default {
6
+ title: 'Forms/Input',
7
+ component: Input,
8
+ args: {
9
+ disabled: false,
10
+ small: false,
11
+ placeholder: 'Placeholder',
12
+ },
13
+ };
14
+
15
+ const Template = (args) => {
16
+ const [_, updateArgs] = useArgs();
17
+ const handleChange = (evt) => {
18
+ updateArgs({ value: evt.target.value });
19
+ };
20
+ return (
21
+ <Input
22
+ // eslint-disable-next-line react/jsx-props-no-spreading
23
+ {...args}
24
+ onChange={handleChange}
25
+ />
26
+ );
27
+ };
28
+ export const Default = Template.bind({});
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
4
+ import styles from './input-group-addon.module.less';
5
+
6
+ export const InputGroupAddon = ({ children, groupOrder, small }) => {
7
+ const order = (() => {
8
+ if (groupOrder) {
9
+ switch (groupOrder) {
10
+ case 'first':
11
+ return styles.groupOrderFirst;
12
+ case 'last':
13
+ return styles.groupOrderLast;
14
+ default:
15
+ return styles.groupOrderMiddle;
16
+ }
17
+ }
18
+ return '';
19
+ })();
20
+ return (
21
+ <span className={cx(styles.addon, order, small ? styles.small : '')}>
22
+ {children}
23
+ </span>
24
+ );
25
+ };
26
+
27
+ InputGroupAddon.defaultProps = {
28
+ groupOrder: null,
29
+ small: false,
30
+ };
31
+
32
+ InputGroupAddon.propTypes = {
33
+ children: PropTypes.node.isRequired,
34
+ groupOrder: PropTypes.string,
35
+ small: PropTypes.bool,
36
+ };
@@ -0,0 +1,31 @@
1
+ @import '../../../style/variables.less';
2
+
3
+ .addon {
4
+ flex-shrink: 0;
5
+ border-radius: @input_border_radius;
6
+ border: 1px solid var(--color-border);
7
+ background: var(--color-background-disabled);
8
+ display: inline-flex;
9
+ align-items: center;
10
+ padding: 0 @input_padding_x;
11
+ color: var(--color-text-muted);
12
+ line-height: 1;
13
+ }
14
+
15
+ .small {
16
+ font-size: @input_font_size_small;
17
+ padding: 0 @input_padding_small_x;
18
+ }
19
+
20
+ .groupOrderFirst,
21
+ .groupOrderMiddle {
22
+ border-top-right-radius: 0 !important;
23
+ border-bottom-right-radius: 0 !important;
24
+ margin-right: -1px;
25
+ }
26
+
27
+ .groupOrderLast,
28
+ .groupOrderMiddle {
29
+ border-top-left-radius: 0 !important;
30
+ border-bottom-left-radius: 0 !important;
31
+ }
@@ -0,0 +1,51 @@
1
+ import React, { Fragment, isValidElement } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
4
+ import styles from './input-group.module.less';
5
+
6
+ const isDOMTypeElement = (element) => {
7
+ return isValidElement(element) && typeof element.type === 'string';
8
+ };
9
+
10
+ export const InputGroup = ({ children, small, width }) => {
11
+ const childElements =
12
+ children instanceof Array
13
+ ? children.filter((c) => isValidElement(c))
14
+ : [children];
15
+ const elements = childElements.map((item, index) => {
16
+ const isDOMType = isDOMTypeElement(item);
17
+ const { groupOrder: groupOrderProp } = !isDOMType
18
+ ? item.props
19
+ : { groupOrder: null };
20
+ const count = childElements.length;
21
+ const isFirst = index === 0;
22
+ const isLast = index === count - 1;
23
+ const isOnly = !count || count === 1;
24
+ const groupOrder =
25
+ groupOrderProp ||
26
+ (isOnly ? null : isFirst ? 'first' : isLast ? 'last' : 'middle');
27
+ return isDOMType ? (
28
+ item
29
+ ) : (
30
+ <Fragment key={index}>
31
+ {React.cloneElement(item, { groupOrder, small })}
32
+ </Fragment>
33
+ );
34
+ });
35
+ return (
36
+ <div className={cx(styles.inputGroup)} style={{ width }}>
37
+ {elements}
38
+ </div>
39
+ );
40
+ };
41
+
42
+ InputGroup.defaultProps = {
43
+ small: false,
44
+ width: '100%',
45
+ };
46
+
47
+ InputGroup.propTypes = {
48
+ children: PropTypes.node.isRequired,
49
+ small: PropTypes.bool,
50
+ width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
51
+ };
@@ -0,0 +1,10 @@
1
+ @import '../../style/variables.less';
2
+
3
+ .inputGroup {
4
+ display: flex;
5
+ max-width: 100%;
6
+
7
+ > *:not(:last-child) {
8
+ margin-right: -1px;
9
+ }
10
+ }
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import {
3
+ InputGroup,
4
+ InputGroupAddon,
5
+ Input,
6
+ Button,
7
+ Menu,
8
+ Select,
9
+ } from '../../..';
10
+
11
+ export default {
12
+ title: 'Forms/InputGroup',
13
+ component: InputGroup,
14
+ args: {},
15
+ };
16
+
17
+ const Template = (args) => {
18
+ return (
19
+ <InputGroup
20
+ // eslint-disable-next-line react/jsx-props-no-spreading
21
+ {...args}
22
+ >
23
+ <InputGroupAddon>$</InputGroupAddon>
24
+ <Input width="100%" name="example" value="123" onChange={() => {}} />
25
+ <Select
26
+ options={[
27
+ { label: 'Aardvarks', value: 'termites' },
28
+ { label: 'Kangaroos', value: 'grass' },
29
+ { label: 'Monkeys', value: 'bananas' },
30
+ { label: 'Possums', value: 'slugs' },
31
+ ]}
32
+ onChange={() => {}}
33
+ value={{ label: 'Monkeys', value: 'bananas' }}
34
+ width="auto"
35
+ native
36
+ />
37
+ <Menu
38
+ menu={{
39
+ label: 'E-06/degC',
40
+ trigger: 'DropDownButton',
41
+ small: args.small,
42
+ sections: [
43
+ {
44
+ type: 'Option',
45
+ label: '403.5433',
46
+ description: 'ft',
47
+ inline: true,
48
+ onClick: () => {},
49
+ },
50
+ {
51
+ type: 'Option',
52
+ label: '0.123',
53
+ description: 'km',
54
+ inline: true,
55
+ onClick: () => {},
56
+ },
57
+ {
58
+ type: 'Option',
59
+ label: '4842.4608',
60
+ description: 'in',
61
+ inline: true,
62
+ onClick: () => {},
63
+ },
64
+ ],
65
+ }}
66
+ />
67
+ <Button name="example" label="Confirm" colored onClick={() => {}} />
68
+ </InputGroup>
69
+ );
70
+ };
71
+ export const Default = Template.bind({});
72
+
73
+ export const FixedWidth = Template.bind({});
74
+ FixedWidth.args = { width: '480px' };
75
+
76
+ export const Small = Template.bind({});
77
+ Small.args = { small: true };
@@ -0,0 +1,61 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { Input, TextArea, Select, RadioButton, FormRow, Field } from '../..';
3
+
4
+ <Meta title="Input Validation" />
5
+
6
+ # Input Validation
7
+
8
+ ## Select
9
+
10
+ ### Invalid states
11
+
12
+ It's possible for a `Select` input to be in an invalid state, where a value is explicitly set via the `value` prop,
13
+ but the option is not available for re-selection in the dropdown (i.e. not in the `options` prop). Some guidelines are
14
+ provided here to help.
15
+
16
+ **Avoid invalid values via the business logic**
17
+
18
+ It's best to prevent invalid values from happening, via the application business logic.
19
+
20
+ If they can happen, handling them is a concern of the business layer. The UI framework is generally only responsible
21
+ for presentation.
22
+
23
+ **Select will always display the value if it is explicitly set**
24
+
25
+ If the `value` prop is set, it will be displayed, even if it is not available for re-selection from the `options` prop.
26
+ The library does not hide or mask set values.
27
+
28
+ **"Soft invalid" values**
29
+
30
+ For a 'soft invalid' state, where the value is usable, but not available for re-reselection, the UI library automatically
31
+ adds a warning state with a tooltip message: "Value no longer available for re-selection". Technically, this should be
32
+ handled by the business logic, not the UI framework, but the behaviour exists for historical reasons.
33
+ In the future it may be optional (via a prop), or deprecated/removed, so it's better to handle it properly in the
34
+ application layer.
35
+
36
+ <Canvas>
37
+ <FormRow>
38
+ <Select
39
+ width="200px"
40
+ options={['Rare', 'Medium', 'Well Done']}
41
+ value="Blue"
42
+ />
43
+ </FormRow>
44
+ </Canvas>
45
+
46
+ **"Hard invalid" value**
47
+
48
+ For a 'hard invalid' state (where the value is unusable, but required), it is recommended for the business logic to not
49
+ set a value (use `null` or `undefined`), and to set the `error` prop with an appropriate message
50
+ (e.g. "Value is required").
51
+
52
+ <Canvas>
53
+ <FormRow>
54
+ <Select
55
+ width="200px"
56
+ options={['Rare', 'Medium', 'Well Done']}
57
+ value={undefined}
58
+ error="Value is required"
59
+ />
60
+ </FormRow>
61
+ </Canvas>
@@ -0,0 +1,201 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import {
3
+ Input,
4
+ Button,
5
+ CheckBox,
6
+ Toggle,
7
+ TextArea,
8
+ Select,
9
+ RadioButton,
10
+ Slider,
11
+ FileInput,
12
+ FormRow,
13
+ OptionDropdown,
14
+ } from '../..';
15
+
16
+ <Meta title="Inputs" />
17
+
18
+ # Inputs
19
+
20
+ React UI Library provides a comprehensive set of user input components.
21
+
22
+ ## Button
23
+
24
+ Use buttons when users need to invoke actions.
25
+
26
+ <Canvas>
27
+ <FormRow>
28
+ <Button label="Save" colored />
29
+ <Button label="Cancel" />
30
+ </FormRow>
31
+ </Canvas>
32
+
33
+ **Guidelines**
34
+
35
+ - only the primary button on a page or view should normally be colored
36
+ - all other buttons should use the default style (try to limit using different variants and colors of buttons)
37
+ - for serious actions (e.g. permanently deleting records), use a red button
38
+
39
+ ## Input
40
+
41
+ Use an `Input` when users need to enter or edit single-line values.
42
+
43
+ <Canvas>
44
+ <FormRow>
45
+ <Input width="200px" />
46
+ </FormRow>
47
+ </Canvas>
48
+
49
+ ### Number Input
50
+
51
+ <Canvas>
52
+ <FormRow>
53
+ <Input width="200px" type="number" value={3} />
54
+ </FormRow>
55
+ </Canvas>
56
+
57
+ ### Date Input
58
+
59
+ <Canvas>
60
+ <FormRow>
61
+ <Input width="200px" value="2020-05-22" type="date" />
62
+ </FormRow>
63
+ </Canvas>
64
+
65
+ ## TextArea
66
+
67
+ Use a `TextArea` when users need to enter or edit multiline text.
68
+
69
+ <Canvas>
70
+ <FormRow>
71
+ <TextArea />
72
+ </FormRow>
73
+ </Canvas>
74
+
75
+ ## Select
76
+
77
+ Use a `Select` component when users need to choose from one or more values from a longer list of options (> 6 options).
78
+
79
+ React UI Library provides two different `Select` components, through one unified interface.
80
+
81
+ ### Native Select
82
+
83
+ Native `Select` is a styled native browser [select input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select).
84
+ You enable it via the `native` prop. It's most useful for simple situations. Its advantages come from the browser
85
+ handling dropdown positioning, performance, and accessibility. Its drawbacks are limited features and styling
86
+ possibilities. A native `Select` looks like this:
87
+
88
+ <Canvas>
89
+ <FormRow>
90
+ <Select native options={['Rare', 'Medium', 'Well Done']} value="Medium" />
91
+ </FormRow>
92
+ </Canvas>
93
+
94
+ ### Custom Select
95
+
96
+ Custom `Select` is a full implementation of a select component as a custom React component. It covers many additional
97
+ features not offered by native select inputs, such as filtering and multi-select. Its drawbacks are that positioning and
98
+ accessibility are not handled out-the-box by the browser, requiring custom code internally within the component. The
99
+ custom `Select` in GUI Library uses [react-laag](https://www.react-laag.com/) as a positioning engine.
100
+
101
+ <Canvas>
102
+ <FormRow>
103
+ <Select
104
+ width="auto"
105
+ options={['Rare', 'Medium', 'Well Done']}
106
+ value="Medium"
107
+ />
108
+ <Select
109
+ width="300px"
110
+ options={['Onions', 'Olives', 'Mushrooms', 'Ham']}
111
+ value={['Olives', 'Mushrooms']}
112
+ />
113
+ </FormRow>
114
+ </Canvas>
115
+
116
+ ## RadioButton
117
+
118
+ Use a `RadioButton` group when users need to choose a single value from a short list of options (< 6 options). They are
119
+ suitable for related but mutually exclusive choices.
120
+
121
+ <Canvas>
122
+ <RadioButton
123
+ options={[
124
+ { label: 'Delivery', value: 'delivery' },
125
+ { label: 'Collection', value: 'collection' },
126
+ ]}
127
+ value={{ label: 'Collection', value: 'collection' }}
128
+ inline
129
+ />
130
+ </Canvas>
131
+
132
+ ## CheckBox
133
+
134
+ Use a `CheckBox` when users need to select between opposite states (switching a binary value on or off). A CheckBox
135
+ should have a label prop which makes the opposite states clear.
136
+
137
+ <Canvas>
138
+ <CheckBox checked label="I agree" />
139
+ </Canvas>
140
+
141
+ You can also use a group of checkboxes when users need to select multiple values from a short list of options
142
+ (< 6 options).
143
+
144
+ <Canvas>
145
+ <FormRow>
146
+ <CheckBox checked label="Breakfast" />
147
+ <CheckBox checked label="Lunch" />
148
+ <CheckBox checked label="Dinner" />
149
+ </FormRow>
150
+ </Canvas>
151
+
152
+ ## OptionDropdown
153
+
154
+ For a larger number of `CheckBox` options and where space is limited, there's a convenience component called `OptionDropdown`,
155
+ which allows selecting a multiple values, by presenting them in a dropdown, with an easy way to select all or clear.
156
+
157
+ <Canvas>
158
+ <OptionDropdown
159
+ label="Meals"
160
+ options={[
161
+ { label: 'Breakfast', value: 'breakfast' },
162
+ { label: 'Lunch', value: 'lunch' },
163
+ { label: 'Dinner', value: 'dinner', selected: true },
164
+ ]}
165
+ onChange={() => {}}
166
+ />
167
+ </Canvas>
168
+
169
+ ## Toggle
170
+
171
+ A `Toggle` is just an alternative variant to a `CheckBox` and has the same use-case (switching a binary value on or off).
172
+
173
+ <Canvas>
174
+ <Toggle checked label="Express mode" onChange={() => {}} />
175
+ </Canvas>
176
+
177
+ ## Slider
178
+
179
+ A `Slider` helps a user to select a numerical value between two endpoints. It can be more convenient than typing values,
180
+ particularly on touch devices.
181
+
182
+ A `Slider` can also be used to set a range of values (start and end points).
183
+
184
+ <Canvas>
185
+ <Slider
186
+ value={30}
187
+ min={0}
188
+ max={100}
189
+ step={1}
190
+ width="200px"
191
+ onChange={() => {}}
192
+ />
193
+ </Canvas>
194
+
195
+ ## File Input
196
+
197
+ Use a `FileInput` when a user needs to upload a file. The `accept` prop allows you to restrict the accepted file types.
198
+
199
+ <Canvas>
200
+ <FileInput accept=".json" width="200px" />
201
+ </Canvas>
@@ -0,0 +1,115 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import PropTypes from 'prop-types';
4
+ import { FaQuestionCircle, FaInfoCircle, FaBook } from 'react-icons/fa';
5
+ import { HiLockClosed, HiLockOpen } from 'react-icons/hi';
6
+ import { Tooltip } from '../tooltip/tooltip';
7
+ import { IconWrapper } from '../heading/heading';
8
+ import styles from './label.module.less';
9
+
10
+ export const Label = ({
11
+ label,
12
+ width,
13
+ helpText,
14
+ helpTextMaxWidth,
15
+ onClickHelp,
16
+ lock,
17
+ info,
18
+ libraryIcon,
19
+ labelLeft,
20
+ }) => {
21
+ return (
22
+ <div className={cx(styles.label, labelLeft ? styles.labelLeft : '')}>
23
+ <label style={{ width: width || '' }}>
24
+ {label}
25
+ <div className={styles.icons}>
26
+ {helpText && !onClickHelp ? (
27
+ <Tooltip text={helpText} maxWidth={helpTextMaxWidth}>
28
+ <FaQuestionCircle className={styles.icon} />
29
+ </Tooltip>
30
+ ) : (
31
+ onClickHelp && (
32
+ <IconWrapper
33
+ onClick={onClickHelp}
34
+ icon={<FaQuestionCircle />}
35
+ isHelp
36
+ />
37
+ )
38
+ )}
39
+ {info && (
40
+ <Tooltip text={info}>
41
+ <FaInfoCircle className={styles.icon} />
42
+ </Tooltip>
43
+ )}
44
+ {lock && lock.visible && lock.onClick && (
45
+ <Tooltip text={lock?.tooltip ?? ''}>
46
+ <IconWrapper
47
+ onClick={lock.onClick}
48
+ isLock
49
+ icon={lock.active ? <HiLockClosed /> : <HiLockOpen />}
50
+ isFaint={!lock.active}
51
+ testId={lock.testId}
52
+ />
53
+ </Tooltip>
54
+ )}
55
+ {libraryIcon && (
56
+ <Tooltip text={libraryIcon?.tooltip ?? ''}>
57
+ <IconWrapper onClick={libraryIcon.onClick} icon={<FaBook />} />
58
+ </Tooltip>
59
+ )}
60
+ </div>
61
+ </label>
62
+ </div>
63
+ );
64
+ };
65
+
66
+ Label.defaultProps = {
67
+ label: null,
68
+ helpText: null,
69
+ helpTextMaxWidth: '300px',
70
+ width: 'auto',
71
+ info: null,
72
+ onClickHelp: null,
73
+ lock: {
74
+ visible: false,
75
+ active: false,
76
+ onClick: () => {},
77
+ tooltip: '',
78
+ testId: undefined,
79
+ },
80
+ libraryIcon: null,
81
+ labelLeft: false,
82
+ };
83
+
84
+ Label.propTypes = {
85
+ label: PropTypes.oneOfType([
86
+ PropTypes.string,
87
+ PropTypes.number,
88
+ PropTypes.node,
89
+ ]),
90
+ /** Adds a help icon with a tooltip */
91
+ helpText: PropTypes.oneOfType([
92
+ PropTypes.string,
93
+ PropTypes.number,
94
+ PropTypes.node,
95
+ ]),
96
+ helpTextMaxWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), //'none' to disable
97
+ width: PropTypes.string,
98
+ /** Adds an info icon with an optional tooltip and onClick event */
99
+ info: PropTypes.string,
100
+ onClickHelp: PropTypes.func,
101
+ /** Adds a lock icon with a tooltip */
102
+ lock: PropTypes.shape({
103
+ visible: PropTypes.bool,
104
+ active: PropTypes.bool,
105
+ onClick: PropTypes.func,
106
+ tooltip: PropTypes.string,
107
+ testId: PropTypes.string,
108
+ }),
109
+ /** Adds a library icon with a tooltip and onClick event */
110
+ libraryIcon: PropTypes.shape({
111
+ onClick: PropTypes.func,
112
+ tooltip: PropTypes.string,
113
+ }),
114
+ labelLeft: PropTypes.bool,
115
+ };