@unbxd-ui/unbxd-react-components 0.2.105 → 0.2.107-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/.babelrc +4 -0
  2. package/.eslintrc.js +38 -0
  3. package/CONTRIBUTE.md +105 -0
  4. package/components/Accordian/Accordian.js +45 -13
  5. package/components/Accordian/Accordian.stories.js +25 -6
  6. package/components/Accordian/index.js +3 -0
  7. package/components/Button/Button.js +26 -9
  8. package/components/Button/Button.stories.js +14 -1
  9. package/components/Button/DropdownButton.js +31 -9
  10. package/components/Button/DropdownButton.stories.js +23 -6
  11. package/components/Button/index.js +8 -1
  12. package/components/DataLoader/DataLoader.js +40 -10
  13. package/components/DataLoader/DataLoader.stories.js +30 -5
  14. package/components/DataLoader/index.js +3 -0
  15. package/components/Form/Checkbox.js +42 -14
  16. package/components/Form/DragDropFileUploader.js +42 -12
  17. package/components/Form/Dropdown.js +181 -104
  18. package/components/Form/FileUploader.js +32 -10
  19. package/components/Form/Form.js +45 -15
  20. package/components/Form/FormElementWrapper.js +7 -2
  21. package/components/Form/Input.js +72 -27
  22. package/components/Form/RadioList.js +48 -17
  23. package/components/Form/RangeSlider.js +73 -37
  24. package/components/Form/ServerPaginatedDDList.js +130 -86
  25. package/components/Form/Textarea.js +43 -18
  26. package/components/Form/Toggle.js +48 -16
  27. package/components/Form/index.js +30 -18
  28. package/components/Form/stories/Checkbox.stories.js +12 -1
  29. package/components/Form/stories/DragDropFileUploader.stories.js +8 -0
  30. package/components/Form/stories/Dropdown.stories.js +24 -6
  31. package/components/Form/stories/FileUploader.stories.js +8 -0
  32. package/components/Form/stories/FormDefault.stories.js +21 -1
  33. package/components/Form/stories/RadioList.stories.js +12 -1
  34. package/components/Form/stories/RangeSlider.stories.js +15 -1
  35. package/components/Form/stories/TextInput.stories.js +19 -3
  36. package/components/Form/stories/Textarea.stories.js +12 -1
  37. package/components/Form/stories/Toggle.stories.js +7 -0
  38. package/components/Form/stories/form.stories.js +40 -3
  39. package/components/InlineModal/InlineModal.js +51 -14
  40. package/components/InlineModal/InlineModal.stories.js +14 -2
  41. package/components/InlineModal/index.js +6 -1
  42. package/components/List/List.js +24 -9
  43. package/components/List/index.js +3 -0
  44. package/components/List/list.stories.js +10 -0
  45. package/components/Modal/Modal.js +49 -17
  46. package/components/Modal/Modal.stories.js +15 -1
  47. package/components/Modal/index.js +3 -0
  48. package/components/NotificationComponent/NotificationComponent.js +34 -11
  49. package/components/NotificationComponent/NotificationComponent.stories.js +6 -0
  50. package/components/NotificationComponent/index.js +3 -0
  51. package/components/ProgressBar/ProgressBar.js +11 -2
  52. package/components/ProgressBar/ProgressBar.stories.js +6 -0
  53. package/components/ProgressBar/index.js +3 -0
  54. package/components/Table/BaseTable.js +134 -69
  55. package/components/Table/PaginationComponent.js +23 -11
  56. package/components/Table/Table.js +149 -68
  57. package/components/Table/Table.stories.js +67 -22
  58. package/components/Table/index.js +4 -0
  59. package/components/TabsComponent/TabsComponent.js +57 -20
  60. package/components/TabsComponent/TabsComponent.stories.js +16 -0
  61. package/components/TabsComponent/index.js +3 -0
  62. package/components/Tooltip/Tooltip.js +47 -25
  63. package/components/Tooltip/Tooltip.stories.js +6 -0
  64. package/components/Tooltip/index.js +3 -0
  65. package/components/core.css +1 -3
  66. package/components/index.js +17 -1
  67. package/components/theme.css +0 -2
  68. package/lib/Readme.md +82 -0
  69. package/lib/components/Accordian/Accordian.js +117 -0
  70. package/lib/components/Accordian/Accordian.stories.js +137 -0
  71. package/lib/components/Accordian/index.js +10 -0
  72. package/lib/components/Button/Button.js +84 -0
  73. package/lib/components/Button/Button.stories.js +89 -0
  74. package/lib/components/Button/DropdownButton.js +77 -0
  75. package/lib/components/Button/DropdownButton.stories.js +51 -0
  76. package/lib/components/Button/index.js +32 -0
  77. package/lib/components/DataLoader/DataLoader.js +88 -0
  78. package/lib/components/DataLoader/DataLoader.stories.js +77 -0
  79. package/lib/components/DataLoader/index.js +10 -0
  80. package/lib/components/Form/Checkbox.js +93 -0
  81. package/lib/components/Form/DragDropFileUploader.js +85 -0
  82. package/lib/components/Form/Dropdown.js +478 -0
  83. package/lib/components/Form/FileUploader.js +81 -0
  84. package/lib/components/Form/Form.js +106 -0
  85. package/lib/components/Form/FormElementWrapper.js +27 -0
  86. package/lib/components/Form/Input.js +140 -0
  87. package/lib/components/Form/RadioList.js +111 -0
  88. package/lib/components/Form/RangeSlider.js +142 -0
  89. package/lib/components/Form/ServerPaginatedDDList.js +267 -0
  90. package/lib/components/Form/Textarea.js +95 -0
  91. package/lib/components/Form/Toggle.js +117 -0
  92. package/lib/components/Form/index.js +73 -0
  93. package/lib/components/Form/stories/Checkbox.stories.js +54 -0
  94. package/lib/components/Form/stories/DragDropFileUploader.stories.js +27 -0
  95. package/lib/components/Form/stories/Dropdown.stories.js +114 -0
  96. package/lib/components/Form/stories/FileUploader.stories.js +31 -0
  97. package/lib/components/Form/stories/FormDefault.stories.js +117 -0
  98. package/lib/components/Form/stories/RadioList.stories.js +55 -0
  99. package/lib/components/Form/stories/RangeSlider.stories.js +82 -0
  100. package/lib/components/Form/stories/TextInput.stories.js +79 -0
  101. package/lib/components/Form/stories/Textarea.stories.js +48 -0
  102. package/lib/components/Form/stories/Toggle.stories.js +25 -0
  103. package/lib/components/Form/stories/form.stories.js +240 -0
  104. package/lib/components/InlineModal/InlineModal.js +146 -0
  105. package/lib/components/InlineModal/InlineModal.stories.js +61 -0
  106. package/lib/components/InlineModal/index.js +24 -0
  107. package/lib/components/List/List.js +76 -0
  108. package/lib/components/List/index.js +10 -0
  109. package/lib/components/List/list.stories.js +38 -0
  110. package/lib/components/Modal/Modal.js +117 -0
  111. package/lib/components/Modal/Modal.stories.js +55 -0
  112. package/lib/components/Modal/index.js +10 -0
  113. package/lib/components/NotificationComponent/NotificationComponent.js +76 -0
  114. package/lib/components/NotificationComponent/NotificationComponent.stories.js +29 -0
  115. package/lib/components/NotificationComponent/index.js +10 -0
  116. package/lib/components/ProgressBar/ProgressBar.js +49 -0
  117. package/lib/components/ProgressBar/ProgressBar.stories.js +21 -0
  118. package/lib/components/ProgressBar/index.js +10 -0
  119. package/lib/components/Table/BaseTable.js +352 -0
  120. package/lib/components/Table/PaginationComponent.js +87 -0
  121. package/lib/components/Table/Table.js +333 -0
  122. package/lib/components/Table/Table.stories.js +204 -0
  123. package/lib/components/Table/index.js +17 -0
  124. package/lib/components/TabsComponent/TabsComponent.js +134 -0
  125. package/lib/components/TabsComponent/TabsComponent.stories.js +65 -0
  126. package/lib/components/TabsComponent/index.js +10 -0
  127. package/lib/components/Tooltip/Tooltip.js +102 -0
  128. package/lib/components/Tooltip/Tooltip.stories.js +25 -0
  129. package/lib/components/Tooltip/index.js +10 -0
  130. package/lib/components/core.css +3 -0
  131. package/lib/components/core.scss +29 -0
  132. package/lib/components/index.js +159 -0
  133. package/lib/components/theme.css +3 -0
  134. package/lib/components/theme.scss +11 -0
  135. package/lib/package-lock.json +20607 -0
  136. package/lib/package.json +94 -0
  137. package/package.json +1 -1
  138. package/src/Intro.stories.mdx +119 -0
  139. package/src/components/Accordian/Accordian.js +89 -0
  140. package/src/components/Accordian/Accordian.stories.js +92 -0
  141. package/src/components/Accordian/accordianCore.css +1 -0
  142. package/src/components/Accordian/accordianCore.scss +8 -0
  143. package/src/components/Accordian/accordianTheme.css +1 -0
  144. package/src/components/Accordian/accordianTheme.scss +6 -0
  145. package/src/components/Accordian/index.js +3 -0
  146. package/src/components/Button/Button.js +67 -0
  147. package/src/components/Button/Button.stories.js +103 -0
  148. package/src/components/Button/DropdownButton.js +60 -0
  149. package/src/components/Button/DropdownButton.stories.js +38 -0
  150. package/src/components/Button/button.css +1 -0
  151. package/src/components/Button/buttonTheme.css +1 -0
  152. package/src/components/Button/buttonTheme.scss +45 -0
  153. package/src/components/Button/index.js +5 -0
  154. package/src/components/DataLoader/DataLoader.js +86 -0
  155. package/src/components/DataLoader/DataLoader.stories.js +72 -0
  156. package/src/components/DataLoader/index.js +3 -0
  157. package/src/components/Form/Checkbox.js +73 -0
  158. package/src/components/Form/DragDropFileUploader.js +67 -0
  159. package/src/components/Form/Dropdown.js +430 -0
  160. package/src/components/Form/FileUploader.js +64 -0
  161. package/src/components/Form/Form.js +83 -0
  162. package/src/components/Form/FormElementWrapper.js +22 -0
  163. package/src/components/Form/Input.js +121 -0
  164. package/src/components/Form/RadioList.js +86 -0
  165. package/src/components/Form/RangeSlider.js +100 -0
  166. package/src/components/Form/ServerPaginatedDDList.js +231 -0
  167. package/src/components/Form/Textarea.js +76 -0
  168. package/src/components/Form/Toggle.js +96 -0
  169. package/src/components/Form/form.css +1 -0
  170. package/src/components/Form/formCore.css +1 -0
  171. package/src/components/Form/formCore.scss +142 -0
  172. package/src/components/Form/formTheme.css +1 -0
  173. package/src/components/Form/formTheme.scss +27 -0
  174. package/src/components/Form/index.js +13 -0
  175. package/src/components/Form/stories/Checkbox.stories.js +41 -0
  176. package/src/components/Form/stories/DragDropFileUploader.stories.js +21 -0
  177. package/src/components/Form/stories/Dropdown.stories.js +124 -0
  178. package/src/components/Form/stories/FileUploader.stories.js +21 -0
  179. package/src/components/Form/stories/FormDefault.stories.js +87 -0
  180. package/src/components/Form/stories/RadioList.stories.js +48 -0
  181. package/src/components/Form/stories/RangeSlider.stories.js +84 -0
  182. package/src/components/Form/stories/TextInput.stories.js +77 -0
  183. package/src/components/Form/stories/Textarea.stories.js +43 -0
  184. package/src/components/Form/stories/Toggle.stories.js +14 -0
  185. package/src/components/Form/stories/form.stories.js +216 -0
  186. package/src/components/InlineModal/InlineModal.js +135 -0
  187. package/src/components/InlineModal/InlineModal.stories.js +54 -0
  188. package/src/components/InlineModal/index.js +4 -0
  189. package/src/components/InlineModal/inlineModal.css +1 -0
  190. package/src/components/InlineModal/inlineModalCore.css +1 -0
  191. package/src/components/InlineModal/inlineModalCore.scss +31 -0
  192. package/src/components/InlineModal/inlineModalTheme.css +1 -0
  193. package/src/components/InlineModal/inlineModalTheme.scss +16 -0
  194. package/src/components/List/List.js +72 -0
  195. package/src/components/List/index.js +3 -0
  196. package/src/components/List/list.css +1 -0
  197. package/src/components/List/list.stories.js +28 -0
  198. package/src/components/List/listCore.css +1 -0
  199. package/src/components/List/listCore.scss +6 -0
  200. package/src/components/List/listTheme.css +0 -0
  201. package/src/components/List/listTheme.scss +0 -0
  202. package/src/components/Modal/Modal.js +99 -0
  203. package/src/components/Modal/Modal.stories.js +54 -0
  204. package/src/components/Modal/index.js +3 -0
  205. package/src/components/Modal/modal.css +1 -0
  206. package/src/components/Modal/modalCore.css +1 -0
  207. package/src/components/Modal/modalCore.scss +34 -0
  208. package/src/components/Modal/modalTheme.css +0 -0
  209. package/src/components/Modal/modalTheme.scss +0 -0
  210. package/src/components/NotificationComponent/NotificationComponent.js +58 -0
  211. package/src/components/NotificationComponent/NotificationComponent.stories.js +28 -0
  212. package/src/components/NotificationComponent/index.js +3 -0
  213. package/src/components/NotificationComponent/notificationComponent.css +1 -0
  214. package/src/components/NotificationComponent/notificationTheme.css +1 -0
  215. package/src/components/NotificationComponent/notificationTheme.scss +30 -0
  216. package/src/components/ProgressBar/ProgressBar.js +45 -0
  217. package/src/components/ProgressBar/ProgressBar.stories.js +14 -0
  218. package/src/components/ProgressBar/index.js +3 -0
  219. package/src/components/ProgressBar/progressBar.css +1 -0
  220. package/src/components/ProgressBar/progressBarCore.css +1 -0
  221. package/src/components/ProgressBar/progressBarCore.scss +14 -0
  222. package/src/components/ProgressBar/progressBarTheme.css +0 -0
  223. package/src/components/ProgressBar/progressBarTheme.scss +0 -0
  224. package/src/components/Table/BaseTable.js +306 -0
  225. package/src/components/Table/PaginationComponent.js +73 -0
  226. package/src/components/Table/Table.js +295 -0
  227. package/src/components/Table/Table.stories.js +198 -0
  228. package/src/components/Table/index.js +8 -0
  229. package/src/components/Table/table.css +1 -0
  230. package/src/components/Table/tableCore.css +1 -0
  231. package/src/components/Table/tableCore.scss +94 -0
  232. package/src/components/Table/tableTheme.css +1 -0
  233. package/src/components/Table/tableTheme.scss +34 -0
  234. package/src/components/TabsComponent/TabsComponent.js +99 -0
  235. package/src/components/TabsComponent/TabsComponent.stories.js +69 -0
  236. package/src/components/TabsComponent/index.js +3 -0
  237. package/src/components/TabsComponent/tabs.css +1 -0
  238. package/src/components/TabsComponent/tabsCore.css +1 -0
  239. package/src/components/TabsComponent/tabsCore.scss +59 -0
  240. package/src/components/TabsComponent/tabsTheme.css +0 -0
  241. package/src/components/TabsComponent/tabsTheme.scss +0 -0
  242. package/src/components/Tooltip/Tooltip.js +87 -0
  243. package/src/components/Tooltip/Tooltip.stories.js +16 -0
  244. package/src/components/Tooltip/index.js +3 -0
  245. package/src/components/Tooltip/tooltipCore.css +1 -0
  246. package/src/components/Tooltip/tooltipCore.scss +22 -0
  247. package/src/components/Tooltip/tooltipTheme.css +1 -0
  248. package/src/components/Tooltip/tooltipTheme.scss +21 -0
  249. package/src/components/core.css +1 -0
  250. package/src/components/core.scss +29 -0
  251. package/src/components/index.js +38 -0
  252. package/src/components/theme.css +1 -0
  253. package/src/components/theme.scss +11 -0
  254. package/src/core/Validators.js +34 -0
  255. package/src/core/customHooks.js +20 -0
  256. package/src/core/dataLoader.js +143 -0
  257. package/src/core/dataLoader.stories.js +123 -0
  258. package/src/core/index.js +3 -0
  259. package/src/core/utils.js +95 -0
  260. package/src/index.js +68 -0
  261. package/vscode-templates/NewStoryTemplate.stories.js +8 -0
  262. /package/{Readme.md → README.md} +0 -0
  263. /package/{components → lib/components}/Accordian/accordianCore.css +0 -0
  264. /package/{components → lib/components}/Accordian/accordianTheme.css +0 -0
  265. /package/{components → lib/components}/Button/buttonTheme.css +0 -0
  266. /package/{components → lib/components}/Form/formCore.css +0 -0
  267. /package/{components → lib/components}/Form/formTheme.css +0 -0
  268. /package/{components → lib/components}/InlineModal/inlineModalCore.css +0 -0
  269. /package/{components → lib/components}/InlineModal/inlineModalTheme.css +0 -0
  270. /package/{components → lib/components}/List/listCore.css +0 -0
  271. /package/{components → lib/components}/List/listTheme.css +0 -0
  272. /package/{components → lib/components}/Modal/modalCore.css +0 -0
  273. /package/{components → lib/components}/Modal/modalTheme.css +0 -0
  274. /package/{components → lib/components}/NotificationComponent/notificationTheme.css +0 -0
  275. /package/{components → lib/components}/ProgressBar/progressBarCore.css +0 -0
  276. /package/{components → lib/components}/ProgressBar/progressBarTheme.css +0 -0
  277. /package/{components → lib/components}/Table/tableCore.css +0 -0
  278. /package/{components → lib/components}/Table/tableTheme.css +0 -0
  279. /package/{components → lib/components}/TabsComponent/tabsCore.css +0 -0
  280. /package/{components → lib/components}/TabsComponent/tabsTheme.css +0 -0
  281. /package/{components → lib/components}/Tooltip/tooltipCore.css +0 -0
  282. /package/{components → lib/components}/Tooltip/tooltipTheme.css +0 -0
  283. /package/{core → lib/core}/Validators.js +0 -0
  284. /package/{core → lib/core}/customHooks.js +0 -0
  285. /package/{core → lib/core}/dataLoader.js +0 -0
  286. /package/{core → lib/core}/dataLoader.stories.js +0 -0
  287. /package/{core → lib/core}/index.js +0 -0
  288. /package/{core → lib/core}/utils.js +0 -0
  289. /package/{index.js → lib/index.js} +0 -0
@@ -0,0 +1,121 @@
1
+ import React, { useContext, useState, forwardRef, useEffect } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { FormContext } from "./Form";
4
+ import FormElementWrapper from "./FormElementWrapper";
5
+ import VALIDATORS from "../../core/Validators";
6
+ import utils from "../../core/utils";
7
+
8
+ let Input = (props, ref) => {
9
+ const [ error, setError ] = useState();
10
+ const {
11
+ label,
12
+ name,
13
+ type,
14
+ className,
15
+ value,
16
+ defaultValue,
17
+ placeholder,
18
+ appearance,
19
+ onChange,
20
+ validations,
21
+ autoComplete,
22
+ showLabel,
23
+ ...restProps
24
+ } = props;
25
+ const { onValueChange } = useContext(FormContext);
26
+
27
+ const postFormValueChange = (value, error) => {
28
+ typeof(onValueChange) === "function" && onValueChange(name, value, error);
29
+ };
30
+
31
+ const onInputChange = (event) => {
32
+ const value = event.target.value;
33
+ const { isValid, error } = utils.checkIfValid(value, validations);
34
+
35
+ if (isValid) {
36
+ setError("");
37
+ } else {
38
+ setError(error);
39
+ }
40
+
41
+ if (typeof(onChange) === "function") {
42
+ onChange(value, error);
43
+ }
44
+
45
+ postFormValueChange(value, error);
46
+ };
47
+
48
+ useEffect(() => {
49
+ /* set the initial form element value in the form context */
50
+ const postValue = typeof(onChange) === "function" ? value : defaultValue;
51
+ const { error } = utils.checkIfValid(postValue, validations);
52
+ postFormValueChange(postValue, error);
53
+ }, [value, defaultValue]);
54
+
55
+ let inputProps = {
56
+ type,
57
+ label,
58
+ name,
59
+ id: name,
60
+ defaultValue,
61
+ placeholder,
62
+ autoComplete,
63
+ className: "RCB-form-el",
64
+ onChange: onInputChange,
65
+ ref,
66
+ ...restProps
67
+ };
68
+
69
+ if (typeof(onChange) === "function") {
70
+ /* make it a controlled component if onChange function is given */
71
+ inputProps.value = value;
72
+ }
73
+
74
+ return (<FormElementWrapper className={className} appearance={appearance}>
75
+ {(showLabel && label) && <label className="RCB-form-el-label" htmlFor={name}>{label}</label>}
76
+ <input {...inputProps} />
77
+ {error && <div className="RCB-form-error">{error}</div>}
78
+ </FormElementWrapper>);
79
+ };
80
+
81
+ Input = forwardRef(Input);
82
+
83
+ Input.propTypes = {
84
+ /** Pass any additional classNames to Input component */
85
+ className: PropTypes.string,
86
+ /** Use it to render different input types like text, password etc. */
87
+ type: PropTypes.string,
88
+ /** indicates whether to show or hide label */
89
+ showLabel: PropTypes.bool,
90
+ /** Label for the input element */
91
+ label: PropTypes.string,
92
+ /** Unique ID for the input element */
93
+ name: PropTypes.string.isRequired,
94
+ /** Will be used only with onChange function, or else ignored */
95
+ value: PropTypes.any,
96
+ defaultValue: PropTypes.any,
97
+ /** Array of validations to perform on the form element value.
98
+ * If the validation fails, you will get an "error" field in the form onSubmit event */
99
+ validations: PropTypes.arrayOf(PropTypes.shape({
100
+ type: PropTypes.oneOf(Object.keys(VALIDATORS)).isRequired,
101
+ message: PropTypes.string.isRequired,
102
+ validator: PropTypes.func
103
+ })),
104
+ placeholder: PropTypes.string,
105
+ /** Define the appearance of the form element. Accepted values are either "inline" or "block" */
106
+ appearance: PropTypes.oneOf(["inline", "block"]),
107
+ /** Becomes a controlled component if onChange function is given */
108
+ onChange: PropTypes.func,
109
+ /* HTML 5 autocomplete attribute */
110
+ autoComplete: PropTypes.string
111
+ };
112
+
113
+ Input.defaultProps = {
114
+ className: "",
115
+ showLabel: true,
116
+ appearance: "inline",
117
+ validations: [],
118
+ autoComplete: "off"
119
+ };
120
+
121
+ export default Input;
@@ -0,0 +1,86 @@
1
+ import React, { useContext, Fragment, useEffect } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { FormContext } from "./Form";
4
+ import FormElementWrapper from "./FormElementWrapper";
5
+
6
+ const RadioList = (props) => {
7
+ const { options, label, name, className, value, defaultValue, appearance, onChange, ...restProps } = props;
8
+ const { onValueChange } = useContext(FormContext);
9
+
10
+ const postFormValueChange = (value) => {
11
+ typeof(onValueChange) === "function" && onValueChange(name, value);
12
+ };
13
+
14
+ const onInputChange = (event) => {
15
+ const value = event.target.value;
16
+
17
+ if (typeof(onChange) === "function") {
18
+ onChange(value);
19
+ }
20
+
21
+ postFormValueChange(value);
22
+ }
23
+
24
+ useEffect(() => {
25
+ /* set the initial form element value in the form context */
26
+ const postValue = typeof(onChange) === "function" ? value : defaultValue;
27
+ postFormValueChange(postValue);
28
+ }, [value, defaultValue]);
29
+
30
+ let inputProps = {
31
+ type: "radio",
32
+ label,
33
+ name,
34
+ className: "RCB-form-el",
35
+ onChange: onInputChange,
36
+ ...restProps
37
+ };
38
+
39
+ return (<FormElementWrapper className={className} appearance={appearance}>
40
+ <label className="RCB-form-el-label">{label}</label>
41
+ {options.map(option => {
42
+ const { id, name } = option;
43
+ const additionalProps = {
44
+ defaultChecked: defaultValue === id
45
+ };
46
+
47
+ if (typeof(onChange) === "function") {
48
+ /* make it a controlled component if onChange function is given */
49
+ additionalProps.checked = value === id;
50
+ }
51
+
52
+ return (<Fragment key={id}>
53
+ <input {...inputProps} id={id} value={id} {...additionalProps} data-hj-allow />
54
+ <label className="RCB-radio-label" htmlFor={id}>{name}</label>
55
+ </Fragment>);
56
+ })}
57
+ </FormElementWrapper>);
58
+ };
59
+
60
+ RadioList.propTypes = {
61
+ /** Pass any additional classNames to Input component */
62
+ className: PropTypes.string,
63
+ /** radio items list */
64
+ options: PropTypes.arrayOf(PropTypes.shape({
65
+ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
66
+ name: PropTypes.string
67
+ })).isRequired,
68
+ /** Label for the input element */
69
+ label: PropTypes.string,
70
+ /** Unique ID for the input element */
71
+ name: PropTypes.string.isRequired,
72
+ /** ID of the selected radio item, will be used only with onChange function, or else ignored */
73
+ value: PropTypes.any,
74
+ defaultValue: PropTypes.any,
75
+ /** Define the appearance of the form element. Accepted values are either "inline" or "block" */
76
+ appearance: PropTypes.oneOf(["inline", "block"]),
77
+ /** Becomes a controlled component if onChange function is given */
78
+ onChange: PropTypes.func
79
+ };
80
+
81
+ RadioList.defaultProps = {
82
+ className: "",
83
+ appearance: "inline"
84
+ };
85
+
86
+ export default RadioList;
@@ -0,0 +1,100 @@
1
+ import React, { useContext, useEffect, useState } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { FormContext } from "./Form";
4
+ import FormElementWrapper from "./FormElementWrapper";
5
+
6
+ const RangeSlider = (props) => {
7
+ const { label, name, min, max, className, value, defaultValue, appearance, onChange, disabled, showBubble, inputStyle = {}, bubbleStyle = {}, inputClassName, ...restProps } = props;
8
+ const { onValueChange } = useContext(FormContext);
9
+ const [ val, setVal ] = useState(value || defaultValue);
10
+
11
+ const postFormValueChange = (value) => {
12
+ typeof(onValueChange) === "function" && onValueChange(name, value);
13
+ };
14
+
15
+ const onInputChange = (event) => {
16
+ const value = event.target.value;
17
+
18
+ // TODO : do validations
19
+
20
+ if (typeof(onChange) === "function") {
21
+ onChange(value);
22
+ }
23
+
24
+ postFormValueChange(value);
25
+ setVal(value);
26
+
27
+ }
28
+
29
+ useEffect(() => {
30
+ /* set the initial form element value in the form context */
31
+ const postValue = typeof(onChange) === "function" ? value : defaultValue;
32
+ postFormValueChange(postValue);
33
+ }, [value, defaultValue]);
34
+
35
+ let inputProps = {
36
+ type: "range",
37
+ min,
38
+ max,
39
+ label,
40
+ name,
41
+ id: name,
42
+ defaultValue,
43
+ disabled,
44
+ className: `RCB-form-el RCB-input-range ${inputClassName}`,
45
+ onChange: onInputChange,
46
+ ...restProps,
47
+ showBubble
48
+ };
49
+
50
+ if (typeof(onChange) === "function") {
51
+ /* make it a controlled component if onChange function is given */
52
+ inputProps.value = value;
53
+ }
54
+
55
+
56
+ return (<FormElementWrapper className={className} appearance={appearance}>
57
+ <label className="RCB-form-el-label" htmlFor={name}>{label}</label>
58
+ <div className="RCB-range-wrapper">
59
+ { showBubble && <div className="RCB-range-value" style={bubbleStyle}><span>{val}</span></div>}
60
+ <input {...inputProps} style={inputStyle} disabled={disabled} data-hj-allow/>
61
+ </div>
62
+ </FormElementWrapper>);
63
+ };
64
+
65
+ RangeSlider.propTypes = {
66
+ /** Pass any additional classNames to Input component container */
67
+ className: PropTypes.string,
68
+ /** Pass any additional classNames to Input component */
69
+ inputClassName: PropTypes.string,
70
+ /** Minimum value for range slider */
71
+ min: PropTypes.string.isRequired,
72
+ /** Maximum value for range slider */
73
+ max: PropTypes.string.isRequired,
74
+ /** Label for the input element */
75
+ label: PropTypes.string,
76
+ /** Unique ID for the input element */
77
+ name: PropTypes.string.isRequired,
78
+ /** Will be used only with onChange function, or else ignored */
79
+ value: PropTypes.any,
80
+ defaultValue: PropTypes.any,
81
+ /** Define the appearance of the form element. Accepted values are either "inline" or "block" */
82
+ appearance: PropTypes.oneOf(["inline", "block"]),
83
+ /** Becomes a controlled component if onChange function is given */
84
+ onChange: PropTypes.func,
85
+ /** Custom Style changes of slider track */
86
+ inputStyle: PropTypes.object,
87
+ /** Custom Style changes of value bubble */
88
+ bubbleStyle: PropTypes.object,
89
+ /** Show bubble with values */
90
+ showBubble: PropTypes.bool,
91
+ /** Indicates if the slider is disabled or enabled */
92
+ disabled: PropTypes.bool
93
+ };
94
+
95
+ RangeSlider.defaultProps = {
96
+ className: "",
97
+ appearance: "inline"
98
+ };
99
+
100
+ export default RangeSlider;
@@ -0,0 +1,231 @@
1
+ import React, { useState, useEffect, useRef, useCallback } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { FixedSizeList } from "react-window";
4
+ import InfiniteLoader from "react-window-infinite-loader";
5
+ import dataLoader from "../../core/dataLoader";
6
+ import utils from "../../core/utils";
7
+
8
+ /* eslint-disable react/prop-types */
9
+
10
+ export const DefaultDropdownItem = (props) => {
11
+ const {
12
+ index,
13
+ style,
14
+ data
15
+ } = props;
16
+ const {
17
+ items,
18
+ isItemLoaded,
19
+ selectItem,
20
+ selectedItems = [],
21
+ idAttribute,
22
+ nameAttribute,
23
+ showClippedContentTitle
24
+ } = data;
25
+
26
+ const itemData = items[index] || {};
27
+ const idValue = itemData[idAttribute];
28
+ const name = itemData[nameAttribute];
29
+ const isSelected = selectedItems.find(obj => obj[idAttribute] === idValue) ? true : false;
30
+ const className = "RCB-list-item " + (isSelected ? "selected" : "");
31
+ let content = name;
32
+
33
+ if (!isItemLoaded(index)) {
34
+ content = "Loading...";
35
+ }
36
+
37
+ return <div style={style} onClick={() => selectItem(itemData)}
38
+ { ...(showClippedContentTitle ? {title: content} : {})}
39
+ className={className}>{content}</div>;
40
+ };
41
+
42
+ const ServerPaginatedDDList = (props) => {
43
+ const {
44
+ selectedItems,
45
+ selectItem,
46
+ idAttribute,
47
+ nameAttribute,
48
+ DropdownItem,
49
+ requestId,
50
+ requestParams,
51
+ responseFormatter,
52
+ pageNoKey,
53
+ perPageKey,
54
+ pageSize,
55
+ maxHeight,
56
+ searchAttribute,
57
+ searchQuery,
58
+ getUrlParams,
59
+ serverListClassName,
60
+ ddItemHeight,
61
+ minPageNo,
62
+ delay = 500,
63
+ loadImmediately = true,
64
+ showClippedContentTitle,
65
+ ...restProps
66
+ } = props;
67
+ const [ items, setItems ] = useState([]);
68
+ const [ itemsResetCounter, setItemsResetCounter ] = useState(loadImmediately?1:0);
69
+ const [ total, setTotal ] = useState(null);
70
+ const [ hasNextPage, setHasNextPage ] = useState(false);
71
+ const [ isNextPageLoading, setIsNextPageLoading ] = useState(false);
72
+ const debouncedFn = useRef();
73
+ const getDefaultPageNo = () => {
74
+ return minPageNo ?? 1
75
+ }
76
+ const pageNoRef = useRef(getDefaultPageNo());
77
+ const searchRef = useRef(searchQuery);
78
+
79
+ const onDataLoaded = (response) => {
80
+ let apiResponse = response;
81
+ setIsNextPageLoading(false);
82
+ if(!loadImmediately && searchRef.current === "") {
83
+ setItems([]);
84
+ setTotal(null);
85
+ return false;
86
+ }
87
+
88
+ if (typeof(responseFormatter) === "function") {
89
+ apiResponse = responseFormatter(response);
90
+ }
91
+
92
+ let { entries, total = 0 } = apiResponse;
93
+
94
+ if (entries === null) {
95
+ entries = [];
96
+ }
97
+
98
+ const totalEntries = [...items, ...entries];
99
+
100
+ if (totalEntries.length < total) {
101
+ setHasNextPage(true);
102
+ } else {
103
+ setHasNextPage(false);
104
+ }
105
+
106
+
107
+ setItems(totalEntries);
108
+ setTotal(total);
109
+ };
110
+
111
+ const makeAPICall = () => {
112
+ setIsNextPageLoading(true);
113
+ const def = dataLoader.getRequestDef({
114
+ requestId,
115
+ params: {
116
+ [pageNoKey]: pageNoRef.current,
117
+ [perPageKey]: pageSize,
118
+ ...(searchRef.current && { [searchAttribute] : searchRef.current}),
119
+ ...requestParams
120
+ },
121
+ urlParams: getUrlParams()
122
+ });
123
+
124
+ def.done(onDataLoaded);
125
+
126
+ return def;
127
+ }
128
+
129
+ /* Callback to be invoked when more rows must be loaded.
130
+ It should return a Promise that is resolved once all data has finished loading.
131
+ */
132
+ const loadNextPage = () => {
133
+ pageNoRef.current = pageNoRef.current + 1;
134
+ return makeAPICall();
135
+ };
136
+
137
+ useEffect(() => {
138
+ /* not the first call */
139
+ if(itemsResetCounter > 0) {
140
+ makeAPICall();
141
+ }
142
+ }, [itemsResetCounter]);
143
+
144
+ useEffect(() => {
145
+ /* search query changed -> reset page no. to 1 */
146
+ if(searchQuery !== searchRef.current) {
147
+ setIsNextPageLoading(true);
148
+ searchRef.current = searchQuery;
149
+ startSearch();
150
+ } else {
151
+ setIsNextPageLoading(false);
152
+ }
153
+ }, [searchQuery]);
154
+ const startSearch = useCallback(()=>{
155
+ if (!debouncedFn.current) {
156
+ debouncedFn.current = utils.debounce(startSearchCallBack, delay);
157
+ }
158
+
159
+ debouncedFn.current();
160
+ },[]);
161
+ const startSearchCallBack = () => {
162
+ pageNoRef.current = getDefaultPageNo();
163
+ setItems([]);
164
+ setTotal(null);
165
+ setItemsResetCounter((prevItemsResetCounter) =>{
166
+ return prevItemsResetCounter+1
167
+ });
168
+ };
169
+
170
+ // If there are more items to be loaded then add an extra row to hold a loading indicator.
171
+ const itemCount = hasNextPage ? items.length + 1 : items.length;
172
+
173
+ // Only load 1 page of items at a time.
174
+ // Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
175
+ const loadMoreItems = isNextPageLoading ? () => {} : loadNextPage;
176
+
177
+ // Every row is loaded except for our loading indicator row.
178
+ const isItemLoaded = index => !hasNextPage || index < items.length;
179
+
180
+ const listProps = {
181
+ selectItem,
182
+ selectedItems,
183
+ idAttribute,
184
+ nameAttribute,
185
+ items,
186
+ isItemLoaded,
187
+ showClippedContentTitle,
188
+ ...restProps
189
+ };
190
+ if(total === null) {
191
+ return []
192
+ }
193
+ if (total === 0) {
194
+ return (
195
+ <div className="RCB-no-data">{`No data found`}</div>
196
+ )
197
+ }
198
+ return (<InfiniteLoader
199
+ // Function responsible for tracking the loaded state of each item.
200
+ isItemLoaded={isItemLoaded}
201
+ // Number of rows in list; can be arbitrary high number if actual number is unknown.
202
+ itemCount={total}
203
+ loadMoreItems={loadMoreItems}
204
+ // Minimum number of rows to be loaded at a time; defaults to 10. This property can be used to batch requests to reduce HTTP requests.
205
+ minimumBatchSize={pageSize}
206
+ // Threshold at which to pre-fetch data; defaults to 15. A threshold of 15 means that data will start loading when a user scrolls within 15 rows.
207
+ threshold={pageSize}>
208
+ {({ onItemsRendered, ref }) => (
209
+ <FixedSizeList
210
+ itemCount={itemCount} itemSize={ddItemHeight}
211
+ onItemsRendered={onItemsRendered}
212
+ className={serverListClassName}
213
+ ref={ref} height={maxHeight} itemData={listProps}>
214
+ {DropdownItem}
215
+ </FixedSizeList>
216
+ )}
217
+ </InfiniteLoader>);
218
+ };
219
+
220
+ ServerPaginatedDDList.propTypes = {
221
+ ddItemHeight: PropTypes.number
222
+ };
223
+
224
+ ServerPaginatedDDList.defaultProps = {
225
+ DropdownItem: DefaultDropdownItem,
226
+ ddItemHeight: 30
227
+ };
228
+
229
+ /* eslint-enable react/prop-types */
230
+
231
+ export default ServerPaginatedDDList;
@@ -0,0 +1,76 @@
1
+ import React, { useContext, useEffect } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { FormContext } from "./Form";
4
+ import FormElementWrapper from "./FormElementWrapper";
5
+
6
+ const Textarea = (props) => {
7
+ const { label, name, className, value, defaultValue, placeholder, appearance, onChange, ...restProps } = props;
8
+ const { onValueChange } = useContext(FormContext);
9
+
10
+ const postFormValueChange = (value) => {
11
+ typeof(onValueChange) === "function" && onValueChange(name, value);
12
+ };
13
+
14
+ const onInputChange = (event) => {
15
+ const value = event.target.value;
16
+
17
+ // TODO : do validations
18
+
19
+ if (typeof(onChange) === "function") {
20
+ onChange(value);
21
+ }
22
+
23
+ postFormValueChange(value);
24
+ }
25
+
26
+ useEffect(() => {
27
+ /* set the initial form element value in the form context */
28
+ const postValue = typeof(onChange) === "function" ? value : defaultValue;
29
+ postFormValueChange(postValue);
30
+ }, [value, defaultValue]);
31
+
32
+ let inputProps = {
33
+ label,
34
+ name,
35
+ id: name,
36
+ defaultValue,
37
+ placeholder,
38
+ className: "RCB-form-el",
39
+ onChange: onInputChange,
40
+ ...restProps
41
+ };
42
+
43
+ if (typeof(onChange) === "function") {
44
+ /* make it a controlled component if onChange function is given */
45
+ inputProps.value = value;
46
+ }
47
+
48
+ return (<FormElementWrapper className={className} appearance={appearance}>
49
+ <label className="RCB-form-el-label" htmlFor={name}>{label}</label>
50
+ <textarea {...inputProps} />
51
+ </FormElementWrapper>);
52
+ };
53
+
54
+ Textarea.propTypes = {
55
+ /** Pass any additional classNames to Textarea component */
56
+ className: PropTypes.string,
57
+ /** Label for the input element */
58
+ label: PropTypes.string,
59
+ /** Unique ID for the input element */
60
+ name: PropTypes.string.isRequired,
61
+ /* Will be used only with onChange function, or else ignored */
62
+ value: PropTypes.any,
63
+ defaultValue: PropTypes.any,
64
+ placeholder: PropTypes.string,
65
+ /* Define the appearance of the form element. Accepted values are either "inline" or "block" */
66
+ appearance: PropTypes.oneOf(["inline", "block"]),
67
+ /* Becomes a controlled component if onChange function is given */
68
+ onChange: PropTypes.func
69
+ };
70
+
71
+ Textarea.defaultProps = {
72
+ className: "",
73
+ appearance: "inline"
74
+ };
75
+
76
+ export default Textarea;