@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.
- package/.babelrc +4 -0
- package/.eslintrc.js +38 -0
- package/CONTRIBUTE.md +105 -0
- package/components/Accordian/Accordian.js +45 -13
- package/components/Accordian/Accordian.stories.js +25 -6
- package/components/Accordian/index.js +3 -0
- package/components/Button/Button.js +26 -9
- package/components/Button/Button.stories.js +14 -1
- package/components/Button/DropdownButton.js +31 -9
- package/components/Button/DropdownButton.stories.js +23 -6
- package/components/Button/index.js +8 -1
- package/components/DataLoader/DataLoader.js +40 -10
- package/components/DataLoader/DataLoader.stories.js +30 -5
- package/components/DataLoader/index.js +3 -0
- package/components/Form/Checkbox.js +42 -14
- package/components/Form/DragDropFileUploader.js +42 -12
- package/components/Form/Dropdown.js +181 -104
- package/components/Form/FileUploader.js +32 -10
- package/components/Form/Form.js +45 -15
- package/components/Form/FormElementWrapper.js +7 -2
- package/components/Form/Input.js +72 -27
- package/components/Form/RadioList.js +48 -17
- package/components/Form/RangeSlider.js +73 -37
- package/components/Form/ServerPaginatedDDList.js +130 -86
- package/components/Form/Textarea.js +43 -18
- package/components/Form/Toggle.js +48 -16
- package/components/Form/index.js +30 -18
- package/components/Form/stories/Checkbox.stories.js +12 -1
- package/components/Form/stories/DragDropFileUploader.stories.js +8 -0
- package/components/Form/stories/Dropdown.stories.js +24 -6
- package/components/Form/stories/FileUploader.stories.js +8 -0
- package/components/Form/stories/FormDefault.stories.js +21 -1
- package/components/Form/stories/RadioList.stories.js +12 -1
- package/components/Form/stories/RangeSlider.stories.js +15 -1
- package/components/Form/stories/TextInput.stories.js +19 -3
- package/components/Form/stories/Textarea.stories.js +12 -1
- package/components/Form/stories/Toggle.stories.js +7 -0
- package/components/Form/stories/form.stories.js +40 -3
- package/components/InlineModal/InlineModal.js +51 -14
- package/components/InlineModal/InlineModal.stories.js +14 -2
- package/components/InlineModal/index.js +6 -1
- package/components/List/List.js +24 -9
- package/components/List/index.js +3 -0
- package/components/List/list.stories.js +10 -0
- package/components/Modal/Modal.js +49 -17
- package/components/Modal/Modal.stories.js +15 -1
- package/components/Modal/index.js +3 -0
- package/components/NotificationComponent/NotificationComponent.js +34 -11
- package/components/NotificationComponent/NotificationComponent.stories.js +6 -0
- package/components/NotificationComponent/index.js +3 -0
- package/components/ProgressBar/ProgressBar.js +11 -2
- package/components/ProgressBar/ProgressBar.stories.js +6 -0
- package/components/ProgressBar/index.js +3 -0
- package/components/Table/BaseTable.js +134 -69
- package/components/Table/PaginationComponent.js +23 -11
- package/components/Table/Table.js +149 -68
- package/components/Table/Table.stories.js +67 -22
- package/components/Table/index.js +4 -0
- package/components/TabsComponent/TabsComponent.js +57 -20
- package/components/TabsComponent/TabsComponent.stories.js +16 -0
- package/components/TabsComponent/index.js +3 -0
- package/components/Tooltip/Tooltip.js +47 -25
- package/components/Tooltip/Tooltip.stories.js +6 -0
- package/components/Tooltip/index.js +3 -0
- package/components/core.css +1 -3
- package/components/index.js +17 -1
- package/components/theme.css +0 -2
- package/lib/Readme.md +82 -0
- package/lib/components/Accordian/Accordian.js +117 -0
- package/lib/components/Accordian/Accordian.stories.js +137 -0
- package/lib/components/Accordian/index.js +10 -0
- package/lib/components/Button/Button.js +84 -0
- package/lib/components/Button/Button.stories.js +89 -0
- package/lib/components/Button/DropdownButton.js +77 -0
- package/lib/components/Button/DropdownButton.stories.js +51 -0
- package/lib/components/Button/index.js +32 -0
- package/lib/components/DataLoader/DataLoader.js +88 -0
- package/lib/components/DataLoader/DataLoader.stories.js +77 -0
- package/lib/components/DataLoader/index.js +10 -0
- package/lib/components/Form/Checkbox.js +93 -0
- package/lib/components/Form/DragDropFileUploader.js +85 -0
- package/lib/components/Form/Dropdown.js +478 -0
- package/lib/components/Form/FileUploader.js +81 -0
- package/lib/components/Form/Form.js +106 -0
- package/lib/components/Form/FormElementWrapper.js +27 -0
- package/lib/components/Form/Input.js +140 -0
- package/lib/components/Form/RadioList.js +111 -0
- package/lib/components/Form/RangeSlider.js +142 -0
- package/lib/components/Form/ServerPaginatedDDList.js +267 -0
- package/lib/components/Form/Textarea.js +95 -0
- package/lib/components/Form/Toggle.js +117 -0
- package/lib/components/Form/index.js +73 -0
- package/lib/components/Form/stories/Checkbox.stories.js +54 -0
- package/lib/components/Form/stories/DragDropFileUploader.stories.js +27 -0
- package/lib/components/Form/stories/Dropdown.stories.js +114 -0
- package/lib/components/Form/stories/FileUploader.stories.js +31 -0
- package/lib/components/Form/stories/FormDefault.stories.js +117 -0
- package/lib/components/Form/stories/RadioList.stories.js +55 -0
- package/lib/components/Form/stories/RangeSlider.stories.js +82 -0
- package/lib/components/Form/stories/TextInput.stories.js +79 -0
- package/lib/components/Form/stories/Textarea.stories.js +48 -0
- package/lib/components/Form/stories/Toggle.stories.js +25 -0
- package/lib/components/Form/stories/form.stories.js +240 -0
- package/lib/components/InlineModal/InlineModal.js +146 -0
- package/lib/components/InlineModal/InlineModal.stories.js +61 -0
- package/lib/components/InlineModal/index.js +24 -0
- package/lib/components/List/List.js +76 -0
- package/lib/components/List/index.js +10 -0
- package/lib/components/List/list.stories.js +38 -0
- package/lib/components/Modal/Modal.js +117 -0
- package/lib/components/Modal/Modal.stories.js +55 -0
- package/lib/components/Modal/index.js +10 -0
- package/lib/components/NotificationComponent/NotificationComponent.js +76 -0
- package/lib/components/NotificationComponent/NotificationComponent.stories.js +29 -0
- package/lib/components/NotificationComponent/index.js +10 -0
- package/lib/components/ProgressBar/ProgressBar.js +49 -0
- package/lib/components/ProgressBar/ProgressBar.stories.js +21 -0
- package/lib/components/ProgressBar/index.js +10 -0
- package/lib/components/Table/BaseTable.js +352 -0
- package/lib/components/Table/PaginationComponent.js +87 -0
- package/lib/components/Table/Table.js +333 -0
- package/lib/components/Table/Table.stories.js +204 -0
- package/lib/components/Table/index.js +17 -0
- package/lib/components/TabsComponent/TabsComponent.js +134 -0
- package/lib/components/TabsComponent/TabsComponent.stories.js +65 -0
- package/lib/components/TabsComponent/index.js +10 -0
- package/lib/components/Tooltip/Tooltip.js +102 -0
- package/lib/components/Tooltip/Tooltip.stories.js +25 -0
- package/lib/components/Tooltip/index.js +10 -0
- package/lib/components/core.css +3 -0
- package/lib/components/core.scss +29 -0
- package/lib/components/index.js +159 -0
- package/lib/components/theme.css +3 -0
- package/lib/components/theme.scss +11 -0
- package/lib/package-lock.json +20607 -0
- package/lib/package.json +94 -0
- package/package.json +1 -1
- package/src/Intro.stories.mdx +119 -0
- package/src/components/Accordian/Accordian.js +89 -0
- package/src/components/Accordian/Accordian.stories.js +92 -0
- package/src/components/Accordian/accordianCore.css +1 -0
- package/src/components/Accordian/accordianCore.scss +8 -0
- package/src/components/Accordian/accordianTheme.css +1 -0
- package/src/components/Accordian/accordianTheme.scss +6 -0
- package/src/components/Accordian/index.js +3 -0
- package/src/components/Button/Button.js +67 -0
- package/src/components/Button/Button.stories.js +103 -0
- package/src/components/Button/DropdownButton.js +60 -0
- package/src/components/Button/DropdownButton.stories.js +38 -0
- package/src/components/Button/button.css +1 -0
- package/src/components/Button/buttonTheme.css +1 -0
- package/src/components/Button/buttonTheme.scss +45 -0
- package/src/components/Button/index.js +5 -0
- package/src/components/DataLoader/DataLoader.js +86 -0
- package/src/components/DataLoader/DataLoader.stories.js +72 -0
- package/src/components/DataLoader/index.js +3 -0
- package/src/components/Form/Checkbox.js +73 -0
- package/src/components/Form/DragDropFileUploader.js +67 -0
- package/src/components/Form/Dropdown.js +430 -0
- package/src/components/Form/FileUploader.js +64 -0
- package/src/components/Form/Form.js +83 -0
- package/src/components/Form/FormElementWrapper.js +22 -0
- package/src/components/Form/Input.js +121 -0
- package/src/components/Form/RadioList.js +86 -0
- package/src/components/Form/RangeSlider.js +100 -0
- package/src/components/Form/ServerPaginatedDDList.js +231 -0
- package/src/components/Form/Textarea.js +76 -0
- package/src/components/Form/Toggle.js +96 -0
- package/src/components/Form/form.css +1 -0
- package/src/components/Form/formCore.css +1 -0
- package/src/components/Form/formCore.scss +142 -0
- package/src/components/Form/formTheme.css +1 -0
- package/src/components/Form/formTheme.scss +27 -0
- package/src/components/Form/index.js +13 -0
- package/src/components/Form/stories/Checkbox.stories.js +41 -0
- package/src/components/Form/stories/DragDropFileUploader.stories.js +21 -0
- package/src/components/Form/stories/Dropdown.stories.js +124 -0
- package/src/components/Form/stories/FileUploader.stories.js +21 -0
- package/src/components/Form/stories/FormDefault.stories.js +87 -0
- package/src/components/Form/stories/RadioList.stories.js +48 -0
- package/src/components/Form/stories/RangeSlider.stories.js +84 -0
- package/src/components/Form/stories/TextInput.stories.js +77 -0
- package/src/components/Form/stories/Textarea.stories.js +43 -0
- package/src/components/Form/stories/Toggle.stories.js +14 -0
- package/src/components/Form/stories/form.stories.js +216 -0
- package/src/components/InlineModal/InlineModal.js +135 -0
- package/src/components/InlineModal/InlineModal.stories.js +54 -0
- package/src/components/InlineModal/index.js +4 -0
- package/src/components/InlineModal/inlineModal.css +1 -0
- package/src/components/InlineModal/inlineModalCore.css +1 -0
- package/src/components/InlineModal/inlineModalCore.scss +31 -0
- package/src/components/InlineModal/inlineModalTheme.css +1 -0
- package/src/components/InlineModal/inlineModalTheme.scss +16 -0
- package/src/components/List/List.js +72 -0
- package/src/components/List/index.js +3 -0
- package/src/components/List/list.css +1 -0
- package/src/components/List/list.stories.js +28 -0
- package/src/components/List/listCore.css +1 -0
- package/src/components/List/listCore.scss +6 -0
- package/src/components/List/listTheme.css +0 -0
- package/src/components/List/listTheme.scss +0 -0
- package/src/components/Modal/Modal.js +99 -0
- package/src/components/Modal/Modal.stories.js +54 -0
- package/src/components/Modal/index.js +3 -0
- package/src/components/Modal/modal.css +1 -0
- package/src/components/Modal/modalCore.css +1 -0
- package/src/components/Modal/modalCore.scss +34 -0
- package/src/components/Modal/modalTheme.css +0 -0
- package/src/components/Modal/modalTheme.scss +0 -0
- package/src/components/NotificationComponent/NotificationComponent.js +58 -0
- package/src/components/NotificationComponent/NotificationComponent.stories.js +28 -0
- package/src/components/NotificationComponent/index.js +3 -0
- package/src/components/NotificationComponent/notificationComponent.css +1 -0
- package/src/components/NotificationComponent/notificationTheme.css +1 -0
- package/src/components/NotificationComponent/notificationTheme.scss +30 -0
- package/src/components/ProgressBar/ProgressBar.js +45 -0
- package/src/components/ProgressBar/ProgressBar.stories.js +14 -0
- package/src/components/ProgressBar/index.js +3 -0
- package/src/components/ProgressBar/progressBar.css +1 -0
- package/src/components/ProgressBar/progressBarCore.css +1 -0
- package/src/components/ProgressBar/progressBarCore.scss +14 -0
- package/src/components/ProgressBar/progressBarTheme.css +0 -0
- package/src/components/ProgressBar/progressBarTheme.scss +0 -0
- package/src/components/Table/BaseTable.js +306 -0
- package/src/components/Table/PaginationComponent.js +73 -0
- package/src/components/Table/Table.js +295 -0
- package/src/components/Table/Table.stories.js +198 -0
- package/src/components/Table/index.js +8 -0
- package/src/components/Table/table.css +1 -0
- package/src/components/Table/tableCore.css +1 -0
- package/src/components/Table/tableCore.scss +94 -0
- package/src/components/Table/tableTheme.css +1 -0
- package/src/components/Table/tableTheme.scss +34 -0
- package/src/components/TabsComponent/TabsComponent.js +99 -0
- package/src/components/TabsComponent/TabsComponent.stories.js +69 -0
- package/src/components/TabsComponent/index.js +3 -0
- package/src/components/TabsComponent/tabs.css +1 -0
- package/src/components/TabsComponent/tabsCore.css +1 -0
- package/src/components/TabsComponent/tabsCore.scss +59 -0
- package/src/components/TabsComponent/tabsTheme.css +0 -0
- package/src/components/TabsComponent/tabsTheme.scss +0 -0
- package/src/components/Tooltip/Tooltip.js +87 -0
- package/src/components/Tooltip/Tooltip.stories.js +16 -0
- package/src/components/Tooltip/index.js +3 -0
- package/src/components/Tooltip/tooltipCore.css +1 -0
- package/src/components/Tooltip/tooltipCore.scss +22 -0
- package/src/components/Tooltip/tooltipTheme.css +1 -0
- package/src/components/Tooltip/tooltipTheme.scss +21 -0
- package/src/components/core.css +1 -0
- package/src/components/core.scss +29 -0
- package/src/components/index.js +38 -0
- package/src/components/theme.css +1 -0
- package/src/components/theme.scss +11 -0
- package/src/core/Validators.js +34 -0
- package/src/core/customHooks.js +20 -0
- package/src/core/dataLoader.js +143 -0
- package/src/core/dataLoader.stories.js +123 -0
- package/src/core/index.js +3 -0
- package/src/core/utils.js +95 -0
- package/src/index.js +68 -0
- package/vscode-templates/NewStoryTemplate.stories.js +8 -0
- /package/{Readme.md → README.md} +0 -0
- /package/{components → lib/components}/Accordian/accordianCore.css +0 -0
- /package/{components → lib/components}/Accordian/accordianTheme.css +0 -0
- /package/{components → lib/components}/Button/buttonTheme.css +0 -0
- /package/{components → lib/components}/Form/formCore.css +0 -0
- /package/{components → lib/components}/Form/formTheme.css +0 -0
- /package/{components → lib/components}/InlineModal/inlineModalCore.css +0 -0
- /package/{components → lib/components}/InlineModal/inlineModalTheme.css +0 -0
- /package/{components → lib/components}/List/listCore.css +0 -0
- /package/{components → lib/components}/List/listTheme.css +0 -0
- /package/{components → lib/components}/Modal/modalCore.css +0 -0
- /package/{components → lib/components}/Modal/modalTheme.css +0 -0
- /package/{components → lib/components}/NotificationComponent/notificationTheme.css +0 -0
- /package/{components → lib/components}/ProgressBar/progressBarCore.css +0 -0
- /package/{components → lib/components}/ProgressBar/progressBarTheme.css +0 -0
- /package/{components → lib/components}/Table/tableCore.css +0 -0
- /package/{components → lib/components}/Table/tableTheme.css +0 -0
- /package/{components → lib/components}/TabsComponent/tabsCore.css +0 -0
- /package/{components → lib/components}/TabsComponent/tabsTheme.css +0 -0
- /package/{components → lib/components}/Tooltip/tooltipCore.css +0 -0
- /package/{components → lib/components}/Tooltip/tooltipTheme.css +0 -0
- /package/{core → lib/core}/Validators.js +0 -0
- /package/{core → lib/core}/customHooks.js +0 -0
- /package/{core → lib/core}/dataLoader.js +0 -0
- /package/{core → lib/core}/dataLoader.stories.js +0 -0
- /package/{core → lib/core}/index.js +0 -0
- /package/{core → lib/core}/utils.js +0 -0
- /package/{index.js → lib/index.js} +0 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import React, { useState, useContext, useRef, Fragment, useEffect, forwardRef, useImperativeHandle } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import InlineModal, { InlineModalActivator, InlineModalBody } from "../InlineModal";
|
|
4
|
+
import List from "../List";
|
|
5
|
+
import { FormContext } from "./Form";
|
|
6
|
+
import FormElementWrapper from "./FormElementWrapper";
|
|
7
|
+
import ServerPaginatedDDList from "./ServerPaginatedDDList";
|
|
8
|
+
import utils from "../../core/utils";
|
|
9
|
+
|
|
10
|
+
const convertToArray = (value) => {
|
|
11
|
+
if (!value) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return Array.isArray(value) ? value : [value];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const getFilteredOptions = (options = [], searchQuery = "", nameAttribute) => {
|
|
19
|
+
return options.filter(obj => {
|
|
20
|
+
const nameValue = obj[nameAttribute].toLowerCase();
|
|
21
|
+
return nameValue.indexOf(searchQuery.toLowerCase()) !== -1;
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/* eslint-disable react/prop-types */
|
|
26
|
+
const DefaultSelectionSummary = ({ selectedItems = [], multiSelect, noSelectionLabel, nameAttribute, showClear, clearSelectedItems }) => {
|
|
27
|
+
let summaryString = "";
|
|
28
|
+
const selectedCount = selectedItems.length;
|
|
29
|
+
|
|
30
|
+
if (multiSelect) {
|
|
31
|
+
summaryString = selectedCount ? `${selectedCount} selected` : noSelectionLabel;
|
|
32
|
+
} else {
|
|
33
|
+
summaryString = selectedCount ? selectedItems[0][nameAttribute] : noSelectionLabel;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (<Fragment><span className="RCB-dd-label">{summaryString}</span>
|
|
37
|
+
<span className="RCB-selection-wrapper">
|
|
38
|
+
{showClear && <span className="RCB-clear-selected" onClick={clearSelectedItems}>Clear</span>}
|
|
39
|
+
<span className="RCB-select-arrow"></span>
|
|
40
|
+
</span>
|
|
41
|
+
</Fragment>);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const DefaultDropdownItem = (props) => {
|
|
45
|
+
const { itemData, selectItem, selectedItems = [], idAttribute, nameAttribute, showClippedContentTitle } = props;
|
|
46
|
+
const idValue = itemData[idAttribute];
|
|
47
|
+
const name = itemData[nameAttribute];
|
|
48
|
+
|
|
49
|
+
const isSelected = selectedItems.find(obj => obj[idAttribute] === idValue) ? true : false;
|
|
50
|
+
const className = "RCB-list-item " + (isSelected ? "selected" : "");
|
|
51
|
+
|
|
52
|
+
if (showClippedContentTitle) {
|
|
53
|
+
return (<li onClick={() => selectItem(itemData)} className={className} title={name}>
|
|
54
|
+
{name}
|
|
55
|
+
</li>);
|
|
56
|
+
} else {
|
|
57
|
+
return (<li onClick={() => selectItem(itemData)} className={className}>
|
|
58
|
+
{name}
|
|
59
|
+
</li>);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
DefaultDropdownItem.propTypes = {
|
|
66
|
+
itemData: PropTypes.object.isRequired,
|
|
67
|
+
selectItem: PropTypes.func.isRequired,
|
|
68
|
+
selectedItems: PropTypes.array,
|
|
69
|
+
idAttribute: PropTypes.string,
|
|
70
|
+
nameAttribute: PropTypes.string,
|
|
71
|
+
showClippedContentTitle: PropTypes.bool
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const NormalList = ({ items = [], selectedItems, selectItem, idAttribute, nameAttribute,
|
|
75
|
+
DropdownItem, ListHeaderItem, showClippedContentTitle,
|
|
76
|
+
...restProps }) => {
|
|
77
|
+
return (
|
|
78
|
+
<Fragment>
|
|
79
|
+
{items.length ? ListHeaderItem : ""}
|
|
80
|
+
<List items={items} {...restProps}
|
|
81
|
+
showNoDataMsg={true}
|
|
82
|
+
ListItem={DropdownItem} selectedItems={selectedItems} selectItem={selectItem} showClippedContentTitle={showClippedContentTitle}
|
|
83
|
+
idAttribute={idAttribute} nameAttribute={nameAttribute} />
|
|
84
|
+
</Fragment>
|
|
85
|
+
)
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
NormalList.defaultProps = {
|
|
89
|
+
DropdownItem: DefaultDropdownItem
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/* eslint-enable react/prop-types */
|
|
93
|
+
|
|
94
|
+
let Dropdown = (props, ref) => {
|
|
95
|
+
const {
|
|
96
|
+
halign,
|
|
97
|
+
label,
|
|
98
|
+
showLabel,
|
|
99
|
+
name,
|
|
100
|
+
SelectionSummary,
|
|
101
|
+
className,
|
|
102
|
+
value,
|
|
103
|
+
defaultValue,
|
|
104
|
+
onChange,
|
|
105
|
+
disabled,
|
|
106
|
+
options,
|
|
107
|
+
showSearch,
|
|
108
|
+
searchPlaceholder,
|
|
109
|
+
idAttribute,
|
|
110
|
+
nameAttribute,
|
|
111
|
+
noSelectionLabel,
|
|
112
|
+
appearance,
|
|
113
|
+
multiSelect,
|
|
114
|
+
DropdownItem,
|
|
115
|
+
validations,
|
|
116
|
+
paginationType,
|
|
117
|
+
requestId,
|
|
118
|
+
requestParams,
|
|
119
|
+
pageNoKey,
|
|
120
|
+
perPageKey,
|
|
121
|
+
pageSize,
|
|
122
|
+
searchAttribute,
|
|
123
|
+
maxHeight,
|
|
124
|
+
responseFormatter,
|
|
125
|
+
getUrlParams,
|
|
126
|
+
showCreateCTA,
|
|
127
|
+
createCTAComponent,
|
|
128
|
+
onCreateCTAClick,
|
|
129
|
+
serverListClassName,
|
|
130
|
+
showClear,
|
|
131
|
+
onClear,
|
|
132
|
+
minPageNo,
|
|
133
|
+
ListHeaderItem,
|
|
134
|
+
onSearchChange: propSearchChange,
|
|
135
|
+
showClippedContentTitle,
|
|
136
|
+
...restProps
|
|
137
|
+
} = props;
|
|
138
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
139
|
+
const debouncedFn = useRef();
|
|
140
|
+
const searchIpRef = useRef();
|
|
141
|
+
|
|
142
|
+
let initialSelected = [];
|
|
143
|
+
const initialValue = typeof (onChange) === "function" ? value : defaultValue;
|
|
144
|
+
|
|
145
|
+
if (typeof (initialValue) !== "undefined") {
|
|
146
|
+
initialSelected = convertToArray(initialValue);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* array of selected item objects */
|
|
150
|
+
let [selectedItems, setSelectedItems] = useState(initialSelected);
|
|
151
|
+
|
|
152
|
+
const { onValueChange } = useContext(FormContext);
|
|
153
|
+
const inlineModalRef = useRef();
|
|
154
|
+
|
|
155
|
+
const hideModal = () => {
|
|
156
|
+
inlineModalRef.current.hideModal();
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const postFormValueChange = (value) => {
|
|
160
|
+
const { error } = utils.checkIfValid(value, validations);
|
|
161
|
+
typeof (onValueChange) === "function" && onValueChange(name, value, error);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const selectItem = (item) => {
|
|
165
|
+
const id = item[idAttribute];
|
|
166
|
+
|
|
167
|
+
if (multiSelect) {
|
|
168
|
+
const isPresent = selectedItems.find(obj => obj[idAttribute] === id);
|
|
169
|
+
if (!isPresent) {
|
|
170
|
+
selectedItems.push(item);
|
|
171
|
+
postFormValueChange(selectedItems);
|
|
172
|
+
typeof (onChange) === "function" && onChange(selectedItems);
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
selectedItems = [item];
|
|
176
|
+
postFormValueChange(item);
|
|
177
|
+
typeof (onChange) === "function" && onChange(item);
|
|
178
|
+
/* close the dropdown */
|
|
179
|
+
hideModal();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
setSelectedItems(selectedItems);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
/* set the initial form element value in the form context */
|
|
187
|
+
let postValue = typeof (onChange) === "function" ? value : defaultValue;
|
|
188
|
+
|
|
189
|
+
if (typeof (postValue) !== "undefined") {
|
|
190
|
+
let arrayPostValue = convertToArray(postValue);
|
|
191
|
+
|
|
192
|
+
postValue = multiSelect ? arrayPostValue : postValue;
|
|
193
|
+
|
|
194
|
+
setSelectedItems(arrayPostValue);
|
|
195
|
+
}
|
|
196
|
+
postFormValueChange(postValue);
|
|
197
|
+
|
|
198
|
+
}, [value, defaultValue]);
|
|
199
|
+
|
|
200
|
+
const debouncedSearchChange = (value) => {
|
|
201
|
+
setSearchQuery(value);
|
|
202
|
+
if (typeof propSearchChange === "function") {
|
|
203
|
+
propSearchChange(value);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const onSearchChange = (event) => {
|
|
208
|
+
event.persist();
|
|
209
|
+
|
|
210
|
+
if (!debouncedFn.current) {
|
|
211
|
+
debouncedFn.current = utils.debounce(debouncedSearchChange, 300);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return debouncedFn.current(event.target.value);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const onModalStateChange = (isModalOpen) => {
|
|
218
|
+
if (isModalOpen && showSearch) {
|
|
219
|
+
searchIpRef.current && searchIpRef.current.focus();
|
|
220
|
+
} else {
|
|
221
|
+
/* modal is closed */
|
|
222
|
+
setSearchQuery("");
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const clearSelectedItems = (evnt) => {
|
|
227
|
+
evnt.stopPropagation();
|
|
228
|
+
setSelectedItems([]);
|
|
229
|
+
typeof (onClear) === "function" && onClear();
|
|
230
|
+
typeof (onChange) === "function" && onChange(null);
|
|
231
|
+
/** Close modal after reset */
|
|
232
|
+
hideModal();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const commonAttributes = {
|
|
236
|
+
selectedItems, selectItem, idAttribute, nameAttribute, DropdownItem, ListHeaderItem, showClippedContentTitle
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
useImperativeHandle(ref, () => ({
|
|
240
|
+
closeDropdown: hideModal
|
|
241
|
+
}));
|
|
242
|
+
|
|
243
|
+
const serverListAttrs = {
|
|
244
|
+
requestId,
|
|
245
|
+
requestParams,
|
|
246
|
+
pageNoKey,
|
|
247
|
+
perPageKey,
|
|
248
|
+
pageSize,
|
|
249
|
+
maxHeight,
|
|
250
|
+
searchQuery,
|
|
251
|
+
searchAttribute,
|
|
252
|
+
responseFormatter,
|
|
253
|
+
getUrlParams,
|
|
254
|
+
serverListClassName,
|
|
255
|
+
minPageNo
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const inlineModalClasses = "RCB-form-el " + (showCreateCTA ? "RCB-dd-with-create" : "");
|
|
259
|
+
|
|
260
|
+
return (<FormElementWrapper className={`RCB-dropdown ${disabled ? "RCB-disabled" : ""} ${className}`} appearance={appearance}>
|
|
261
|
+
{showLabel && <label className="RCB-form-el-label" htmlFor={name}>{label}</label>}
|
|
262
|
+
<InlineModal className={inlineModalClasses} ref={inlineModalRef} halign={halign} onModalStateChange={onModalStateChange}>
|
|
263
|
+
<InlineModalActivator>
|
|
264
|
+
<SelectionSummary
|
|
265
|
+
selectedItems={selectedItems}
|
|
266
|
+
noSelectionLabel={noSelectionLabel}
|
|
267
|
+
multiSelect={multiSelect} nameAttribute={nameAttribute} {...restProps}
|
|
268
|
+
showClear={showClear} clearSelectedItems={clearSelectedItems} />
|
|
269
|
+
</InlineModalActivator>
|
|
270
|
+
<InlineModalBody>
|
|
271
|
+
{showSearch && <div className="RCB-dd-search">
|
|
272
|
+
<span className="RCB-dd-search-icon"></span>
|
|
273
|
+
{/* data-hj-allow attribute added for hotjar */}
|
|
274
|
+
<input type="text" className="RCB-dd-search-ip" placeholder={searchPlaceholder} onChange={onSearchChange} ref={searchIpRef} data-hj-allow />
|
|
275
|
+
</div>}
|
|
276
|
+
{paginationType === "SERVER" ?
|
|
277
|
+
<ServerPaginatedDDList {...commonAttributes} {...serverListAttrs} {...restProps} /> :
|
|
278
|
+
<NormalList {...commonAttributes} {...restProps}
|
|
279
|
+
items={getFilteredOptions(options, searchQuery, nameAttribute)} />}
|
|
280
|
+
{showCreateCTA && <div className="RCB-dd-create-cta" onClick={onCreateCTAClick}>{createCTAComponent}</div>}
|
|
281
|
+
</InlineModalBody>
|
|
282
|
+
</InlineModal>
|
|
283
|
+
</FormElementWrapper>);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// const VALUE_SHAPE = PropTypes.shape({
|
|
287
|
+
// id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
288
|
+
// name: PropTypes.string
|
|
289
|
+
// });
|
|
290
|
+
|
|
291
|
+
Dropdown = forwardRef(Dropdown);
|
|
292
|
+
|
|
293
|
+
Dropdown.propTypes = {
|
|
294
|
+
/** Pass any additional classNames to Dropdown component */
|
|
295
|
+
className: PropTypes.string,
|
|
296
|
+
/** Pass infinite fixed list classname to Dropdown component */
|
|
297
|
+
serverListClassName: PropTypes.string,
|
|
298
|
+
/** Horizontal alignment of the dropdown body */
|
|
299
|
+
halign: PropTypes.oneOf(["left", "right"]),
|
|
300
|
+
/** Label for the dropdown element */
|
|
301
|
+
label: PropTypes.string,
|
|
302
|
+
/** indicates whether to show or hide label */
|
|
303
|
+
showLabel: PropTypes.bool,
|
|
304
|
+
/** Unique ID for the input element */
|
|
305
|
+
name: PropTypes.string.isRequired,
|
|
306
|
+
/** Label for dropdown activator */
|
|
307
|
+
noSelectionLabel: PropTypes.string,
|
|
308
|
+
/** Selection items list */
|
|
309
|
+
options: PropTypes.arrayOf(PropTypes.shape({
|
|
310
|
+
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
311
|
+
name: PropTypes.string
|
|
312
|
+
})),
|
|
313
|
+
/** array of selected item objects, only considered if onChange event is given */
|
|
314
|
+
value: PropTypes.any,
|
|
315
|
+
/** array of default selected item objects */
|
|
316
|
+
defaultValue: PropTypes.any,
|
|
317
|
+
onChange: PropTypes.func,
|
|
318
|
+
/** pass true if dropdown has to be disabled */
|
|
319
|
+
disabled: PropTypes.bool,
|
|
320
|
+
/* set to true if you want search ability for dropdown items */
|
|
321
|
+
showSearch: PropTypes.bool,
|
|
322
|
+
/* placeholder to show in the search box */
|
|
323
|
+
searchPlaceholder: PropTypes.string,
|
|
324
|
+
/** Is dropdown multi select or single select */
|
|
325
|
+
multiSelect: PropTypes.bool,
|
|
326
|
+
/** ID attribute key to use when rendering the dropdown items, if the ID attribute is other than "id" */
|
|
327
|
+
idAttribute: PropTypes.string,
|
|
328
|
+
/** name attribute key to use when rendering the dropdown items, if the name attribute is other than "name" */
|
|
329
|
+
nameAttribute: PropTypes.string,
|
|
330
|
+
/** Add title attribute to list element for large data */
|
|
331
|
+
showClippedContentTitle: PropTypes.bool,
|
|
332
|
+
/** Provide a custom element for rendering dropdown item */
|
|
333
|
+
DropdownItem: PropTypes.oneOfType([
|
|
334
|
+
PropTypes.instanceOf(Element),
|
|
335
|
+
PropTypes.func
|
|
336
|
+
]),
|
|
337
|
+
/** Pass true to show a create CTA at the end of the dropdown */
|
|
338
|
+
showCreateCTA: PropTypes.bool,
|
|
339
|
+
/** Customize the create CTA HTML by passing a createCTAComponent */
|
|
340
|
+
createCTAComponent: PropTypes.any,
|
|
341
|
+
/** Callback that gets called when Create CTA button is clicked */
|
|
342
|
+
onCreateCTAClick: PropTypes.func,
|
|
343
|
+
/** Pass this component to customise the selection summary HTML.
|
|
344
|
+
* The array of selected item objects will be sent as props
|
|
345
|
+
*/
|
|
346
|
+
SelectionSummary: PropTypes.func,
|
|
347
|
+
/** Define the appearance of the form element. Accepted values are either "inline" or "block" */
|
|
348
|
+
appearance: PropTypes.oneOf(["inline", "block"]),
|
|
349
|
+
/** Array of validations to perform on the form element value.
|
|
350
|
+
* If the validation fails, you will get an "error" field in the form onSubmit event */
|
|
351
|
+
validations: PropTypes.arrayOf(PropTypes.shape({
|
|
352
|
+
type: PropTypes.oneOf(["REQUIRED", "CUSTOM"]).isRequired,
|
|
353
|
+
message: PropTypes.string.isRequired,
|
|
354
|
+
validator: PropTypes.func
|
|
355
|
+
})),
|
|
356
|
+
/** Type of pagination for the dropdown list items. Send "SERVER" for server side pagination */
|
|
357
|
+
paginationType: PropTypes.oneOf(["NONE", "SERVER"]),
|
|
358
|
+
/** If paginationType is "SERVER", pass the requestId for the server request */
|
|
359
|
+
requestId: function (props, propName) {
|
|
360
|
+
if (props["paginationType"] == "SERVER" && (!props[propName] || typeof (props[propName]) === "undefined")) {
|
|
361
|
+
return new Error("Please provide a requestId for paginationType 'SERVER'!");
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
/** If paginationType is "SERVER", pass any additional params to be sent to the server request */
|
|
365
|
+
requestParams: PropTypes.object,
|
|
366
|
+
/** If paginationType is "SERVER", pass the pageNo. attribute to be sent to the server request */
|
|
367
|
+
pageNoKey: PropTypes.string,
|
|
368
|
+
/** If paginationType is "SERVER", pass the pageSize attribute to be sent to the server request */
|
|
369
|
+
perPageKey: PropTypes.string,
|
|
370
|
+
/** If paginationType is "SERVER", max height of the dropdown container */
|
|
371
|
+
maxHeight: PropTypes.number,
|
|
372
|
+
/** If paginationType is "SERVER", height of each dropdown item */
|
|
373
|
+
ddItemHeight: PropTypes.number,
|
|
374
|
+
/** If paginationType is "SERVER", max number of items to show for one page in the dropdown container */
|
|
375
|
+
pageSize: PropTypes.number,
|
|
376
|
+
/** Default page number to use for server paginated list */
|
|
377
|
+
minPageNo: PropTypes.number,
|
|
378
|
+
/** If paginationType is "SERVER" & showSearch is true, pass the search attribute to be sent to the server request */
|
|
379
|
+
searchAttribute: PropTypes.string,
|
|
380
|
+
/** If paginationType is "SERVER",
|
|
381
|
+
* component expects the response to be of the form
|
|
382
|
+
* { [pageNoKey]: <pageNo>, [perPageKey]: <pageSize>, total: <totalCount>, entries: [{}] }
|
|
383
|
+
* If your data is not in this format, use the responseFormatter to format the data to this structure.
|
|
384
|
+
* Input to this function is the response received from your API
|
|
385
|
+
* */
|
|
386
|
+
responseFormatter: PropTypes.func,
|
|
387
|
+
/** If paginationType is "SERVER", function that is expected to return the URL Params object */
|
|
388
|
+
getUrlParams: PropTypes.func,
|
|
389
|
+
|
|
390
|
+
/** Show the optional clear button for resetting selections */
|
|
391
|
+
showClear: PropTypes.bool,
|
|
392
|
+
/** Custom on clear function */
|
|
393
|
+
onClear: PropTypes.func,
|
|
394
|
+
/** Callback on query search in dropdown */
|
|
395
|
+
onSearchChange: PropTypes.func,
|
|
396
|
+
/** List header Component */
|
|
397
|
+
ListHeaderItem: PropTypes.string
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
Dropdown.defaultProps = {
|
|
401
|
+
className: "",
|
|
402
|
+
label: "",
|
|
403
|
+
showLabel: true,
|
|
404
|
+
showSearch: false,
|
|
405
|
+
searchPlaceholder: "Search",
|
|
406
|
+
searchAttribute: "search",
|
|
407
|
+
multiSelect: false,
|
|
408
|
+
idAttribute: "id",
|
|
409
|
+
nameAttribute: "name",
|
|
410
|
+
noSelectionLabel: "Select",
|
|
411
|
+
appearance: "inline",
|
|
412
|
+
halign: "left",
|
|
413
|
+
validations: [],
|
|
414
|
+
paginationType: "NONE",
|
|
415
|
+
pageNoKey: "page",
|
|
416
|
+
perPageKey: "count",
|
|
417
|
+
maxHeight: 200,
|
|
418
|
+
pageSize: 10,
|
|
419
|
+
getUrlParams: () => ({}),
|
|
420
|
+
SelectionSummary: DefaultSelectionSummary,
|
|
421
|
+
showCreateCTA: false,
|
|
422
|
+
serverListClassName: "",
|
|
423
|
+
createCTAComponent: <span>Create New</span>,
|
|
424
|
+
onCreateCTAClick: () => { },
|
|
425
|
+
showClear: false,
|
|
426
|
+
ListHeaderItem: "",
|
|
427
|
+
onClear: () => { }
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
export default Dropdown;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { FormContext } from "./Form";
|
|
4
|
+
import FormElementWrapper from "./FormElementWrapper";
|
|
5
|
+
|
|
6
|
+
const FileUploader = (props) => {
|
|
7
|
+
const { label, name, multiple, accept, className, appearance, onChange, children } = props;
|
|
8
|
+
const { onValueChange } = useContext(FormContext);
|
|
9
|
+
|
|
10
|
+
const onFileChange = (event) => {
|
|
11
|
+
const value = event.target.files;
|
|
12
|
+
|
|
13
|
+
if (typeof(onChange) === "function") {
|
|
14
|
+
onChange(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
typeof(onValueChange) === "function" && onValueChange(name, value);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
let inputProps = {
|
|
21
|
+
type: "file",
|
|
22
|
+
label,
|
|
23
|
+
name,
|
|
24
|
+
id: name,
|
|
25
|
+
multiple: multiple,
|
|
26
|
+
accept: accept,
|
|
27
|
+
className: "RCB-form-el",
|
|
28
|
+
onChange: onFileChange
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (<FormElementWrapper className={className} appearance={appearance}>
|
|
32
|
+
<label className="RCB-form-el-label">{label}</label>
|
|
33
|
+
<input {...inputProps} className="RCB-hidden" />
|
|
34
|
+
<label htmlFor={name} className="RCB-file-input">
|
|
35
|
+
<div className="RCB-no-pointer">{children}</div>
|
|
36
|
+
</label>
|
|
37
|
+
</FormElementWrapper>);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
FileUploader.propTypes = {
|
|
41
|
+
/** Pass any additional classNames to Input component */
|
|
42
|
+
className: PropTypes.string,
|
|
43
|
+
/** Label for the input element */
|
|
44
|
+
label: PropTypes.string,
|
|
45
|
+
/** Unique ID for the input element */
|
|
46
|
+
name: PropTypes.string.isRequired,
|
|
47
|
+
/** set to true to upload multiple files at once */
|
|
48
|
+
multiple: PropTypes.bool,
|
|
49
|
+
/** mime type of the acceptable files */
|
|
50
|
+
accept: PropTypes.string,
|
|
51
|
+
/** Define the appearance of the form element. Accepted values are either "inline" or "block" */
|
|
52
|
+
appearance: PropTypes.oneOf(["inline", "block"]),
|
|
53
|
+
/** Becomes a controlled component if onChange function is given */
|
|
54
|
+
onChange: PropTypes.func
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
FileUploader.defaultProps = {
|
|
58
|
+
className: "",
|
|
59
|
+
appearance: "inline",
|
|
60
|
+
multiple: false,
|
|
61
|
+
accept: "image/*"
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default FileUploader;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React, { useState, useRef, createContext, useImperativeHandle, forwardRef, useEffect } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import dequal from "dequal";
|
|
4
|
+
import cloneDeep from "lodash.clonedeep";
|
|
5
|
+
|
|
6
|
+
export const FormContext = createContext({
|
|
7
|
+
onValueChange: () => {}
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
let Form = (props, ref) => {
|
|
11
|
+
const [ formData, setFormData ] = useState({});
|
|
12
|
+
const [ formErrors, setFormErrors ] = useState({});
|
|
13
|
+
const [ formRefreshCount, setFormRefreshCount ] = useState(0);
|
|
14
|
+
const { className, onChange, onSubmit } = props;
|
|
15
|
+
const dataRef = useRef();
|
|
16
|
+
|
|
17
|
+
const getFormData = () => {
|
|
18
|
+
return { data: formData, errors: formErrors };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/* add methods that can be accessed via this component's ref */
|
|
22
|
+
useImperativeHandle(ref, () => ({
|
|
23
|
+
getFormData: getFormData
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
const onValueChange = (key, value, error) => {
|
|
27
|
+
formData[key] = value;
|
|
28
|
+
setFormData(formData);
|
|
29
|
+
|
|
30
|
+
if (error) {
|
|
31
|
+
formErrors[key] = error;
|
|
32
|
+
} else {
|
|
33
|
+
/* remove the error value */
|
|
34
|
+
delete formErrors[key];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
setFormErrors(formErrors);
|
|
38
|
+
setFormRefreshCount(formRefreshCount + 1);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const onFormSubmit = (event) => {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
onSubmit(getFormData());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
/*
|
|
48
|
+
As useEffect does not do a deep comparision on dependent props,
|
|
49
|
+
do a manual deep comparision to decide whether data changed
|
|
50
|
+
*/
|
|
51
|
+
if (typeof(onChange) === "function") {
|
|
52
|
+
const formData = getFormData();
|
|
53
|
+
|
|
54
|
+
if (!dequal(formData, dataRef.current)) {
|
|
55
|
+
dataRef.current = cloneDeep(formData);
|
|
56
|
+
onChange(formData);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}, [formRefreshCount]);
|
|
60
|
+
|
|
61
|
+
return (<form onSubmit={onFormSubmit} className={className}>
|
|
62
|
+
<FormContext.Provider value={{onValueChange: onValueChange}}>
|
|
63
|
+
{props.children}
|
|
64
|
+
</FormContext.Provider>
|
|
65
|
+
</form>);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
Form = forwardRef(Form);
|
|
69
|
+
|
|
70
|
+
Form.propTypes = {
|
|
71
|
+
/** Pass any additional classNames to Form component */
|
|
72
|
+
className: PropTypes.string,
|
|
73
|
+
/** Pass a callback function to listen to changes on any of the form elements */
|
|
74
|
+
onChange: PropTypes.func,
|
|
75
|
+
/** Pass a callback function to listen to form submit event */
|
|
76
|
+
onSubmit: PropTypes.func
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
Form.defaultProps = {
|
|
80
|
+
className: ""
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export default Form;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
const FormElementWrapper = (props) => {
|
|
5
|
+
const { className, children, appearance } = props;
|
|
6
|
+
|
|
7
|
+
return (<div className={`RCB-form-el-cont RCB-form-el-${appearance} ${className}`}>
|
|
8
|
+
{children}
|
|
9
|
+
</div>);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
FormElementWrapper.propTypes = {
|
|
13
|
+
/** Pass any additional classNames to Form component */
|
|
14
|
+
className: PropTypes.string,
|
|
15
|
+
appearance: PropTypes.string
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
FormElementWrapper.defaultProps = {
|
|
19
|
+
appearance: "inline"
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default FormElementWrapper;
|