@plusscommunities/pluss-feature-builder-web-d 1.0.2-beta.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 (117) hide show
  1. package/.babelrc +4 -0
  2. package/dist/index.cjs.js +7792 -0
  3. package/package.json +54 -0
  4. package/rollup.config.js +68 -0
  5. package/src/actions/featureBuilderStringsActions.js +88 -0
  6. package/src/actions/featureDefinitionsIndex.js +258 -0
  7. package/src/actions/formActions.js +311 -0
  8. package/src/actions/index.js +12 -0
  9. package/src/actions/listingActions.js +350 -0
  10. package/src/actions/wizardActions.js +240 -0
  11. package/src/components/ActivityCardExample.jsx +86 -0
  12. package/src/components/ActivityCardExample.module.css +130 -0
  13. package/src/components/BackgroundLoader.jsx +33 -0
  14. package/src/components/BackgroundLoader.module.css +46 -0
  15. package/src/components/BaseFieldConfig.jsx +305 -0
  16. package/src/components/BaseFieldConfig.module.css +42 -0
  17. package/src/components/CenteredContainer.jsx +29 -0
  18. package/src/components/CenteredContainer.module.css +171 -0
  19. package/src/components/DeleteConfirmationPopup.jsx +95 -0
  20. package/src/components/DeleteConfirmationPopup.module.css +12 -0
  21. package/src/components/ErrorBoundary.jsx +134 -0
  22. package/src/components/ErrorBoundary.module.css +77 -0
  23. package/src/components/ErrorMessage.jsx +85 -0
  24. package/src/components/ErrorMessage.module.css +116 -0
  25. package/src/components/ExampleDisplay.jsx +26 -0
  26. package/src/components/ExampleDisplay.module.css +3 -0
  27. package/src/components/FeatureBuilderSidebar.jsx +84 -0
  28. package/src/components/FeatureBuilderSuccessPopup.jsx +55 -0
  29. package/src/components/FeatureBuilderSuccessPopup.module.css +43 -0
  30. package/src/components/FeatureBuilderWelcomePopup.jsx +51 -0
  31. package/src/components/FeatureBuilderWelcomePopup.module.css +21 -0
  32. package/src/components/FeatureListingCard.jsx +104 -0
  33. package/src/components/FeatureListingCard.module.css +62 -0
  34. package/src/components/Fields.jsx +460 -0
  35. package/src/components/Fields.module.css +159 -0
  36. package/src/components/IconLoader.jsx +153 -0
  37. package/src/components/IconLoader.module.css +92 -0
  38. package/src/components/IconSelector.jsx +112 -0
  39. package/src/components/IconSelector.module.css +197 -0
  40. package/src/components/ListingEditor.jsx +406 -0
  41. package/src/components/ListingEditor.module.css +14 -0
  42. package/src/components/ListingSuccessPopup.jsx +52 -0
  43. package/src/components/LoadingScreen.jsx +54 -0
  44. package/src/components/LoadingScreen.module.css +103 -0
  45. package/src/components/LoadingState.jsx +40 -0
  46. package/src/components/LoadingState.module.css +18 -0
  47. package/src/components/PreviewFull.js +24 -0
  48. package/src/components/PreviewFull.module.css +11 -0
  49. package/src/components/PreviewGrid.js +14 -0
  50. package/src/components/PreviewWidget.js +27 -0
  51. package/src/components/PreviewWidget.module.css +15 -0
  52. package/src/components/SidebarLayout.jsx +292 -0
  53. package/src/components/SidebarLayout.module.css +145 -0
  54. package/src/components/SkeletonLoader.jsx +128 -0
  55. package/src/components/SkeletonLoader.module.css +295 -0
  56. package/src/components/SortButtonGroup.jsx +34 -0
  57. package/src/components/SortButtonGroup.module.css +51 -0
  58. package/src/components/ToastContainer.jsx +98 -0
  59. package/src/components/ToastContainer.module.css +156 -0
  60. package/src/components/ToggleSwitch.js +40 -0
  61. package/src/components/ToggleSwitch.module.css +48 -0
  62. package/src/components/TwoColumnInput.jsx +29 -0
  63. package/src/components/TwoColumnInput.module.css +32 -0
  64. package/src/components/ViewFull.js +139 -0
  65. package/src/components/ViewFull.module.css +71 -0
  66. package/src/components/ViewWidget.js +62 -0
  67. package/src/components/ViewWidget.module.css +28 -0
  68. package/src/components/iconCategories.js +135 -0
  69. package/src/components/iconImports.js +409 -0
  70. package/src/components/index.js +61 -0
  71. package/src/components/listing/FileListItem.jsx +86 -0
  72. package/src/components/listing/GalleryDisplay.jsx +331 -0
  73. package/src/components/listing/GalleryDisplay.module.css +309 -0
  74. package/src/components/listing/ListingCTAInput.jsx +82 -0
  75. package/src/components/listing/ListingDescriptionInput.jsx +73 -0
  76. package/src/components/listing/ListingField.jsx +101 -0
  77. package/src/components/listing/ListingField.module.css +106 -0
  78. package/src/components/listing/ListingFileInput.jsx +255 -0
  79. package/src/components/listing/ListingFileInput.module.css +192 -0
  80. package/src/components/listing/ListingForm.jsx +90 -0
  81. package/src/components/listing/ListingForm.module.css +38 -0
  82. package/src/components/listing/ListingGalleryInput.jsx +236 -0
  83. package/src/components/listing/ListingGalleryInput.module.css +131 -0
  84. package/src/components/listing/ListingImageInput.jsx +153 -0
  85. package/src/components/listing/ListingTextInput.jsx +72 -0
  86. package/src/feature.config.js +130 -0
  87. package/src/helper/index.js +135 -0
  88. package/src/hooks/useFeatureDefinitionLoader.js +62 -0
  89. package/src/images/full.png +0 -0
  90. package/src/images/fullNoTitle.png +0 -0
  91. package/src/images/previewWidget.png +0 -0
  92. package/src/images/widget.png +0 -0
  93. package/src/index.js +38 -0
  94. package/src/pages/CreateListingPage.jsx +49 -0
  95. package/src/pages/EditListingPage.jsx +58 -0
  96. package/src/reducers/featureBuilderReducer.js +744 -0
  97. package/src/screens/CreateListing.module.css +45 -0
  98. package/src/screens/Form.module.css +734 -0
  99. package/src/screens/FormFieldsStep.jsx +689 -0
  100. package/src/screens/FormLayoutStep.jsx +445 -0
  101. package/src/screens/FormOverviewStep.jsx +396 -0
  102. package/src/screens/ListingScreen.jsx +478 -0
  103. package/src/screens/ListingScreen.module.css +333 -0
  104. package/src/selectors/featureBuilderSelectors.js +529 -0
  105. package/src/types/index.js +91 -0
  106. package/src/utils/textUtils.js +89 -0
  107. package/src/validators/galleryValidators.js +345 -0
  108. package/src/values.config.a.js +49 -0
  109. package/src/values.config.b.js +49 -0
  110. package/src/values.config.c.js +49 -0
  111. package/src/values.config.d.js +49 -0
  112. package/src/values.config.js +49 -0
  113. package/src/webapi/featureDefinitionActions.js +0 -0
  114. package/src/webapi/featuresActions.js +90 -0
  115. package/src/webapi/helper.js +4 -0
  116. package/src/webapi/index.js +12 -0
  117. package/src/webapi/listingActions.js +176 -0
@@ -0,0 +1,73 @@
1
+ import React from "react";
2
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3
+ import { GenericInput, Text } from "../index.js";
4
+ import { iconImports } from "../iconImports.js";
5
+ import styles from "./ListingField.module.css";
6
+
7
+ const ListingDescriptionInput = ({
8
+ field,
9
+ value,
10
+ onChange,
11
+ showError,
12
+ errorMessage,
13
+ }) => {
14
+ const { label, placeholder, isRequired, helpText } = field.values;
15
+
16
+ const handleChange = (e) => {
17
+ onChange(field.id, e.target.value);
18
+ };
19
+
20
+ const isValid = () => {
21
+ if (isRequired) {
22
+ const isEmpty =
23
+ !value || (typeof value === "string" && value.trim() === "");
24
+ return !isEmpty;
25
+ }
26
+ return true;
27
+ };
28
+
29
+ const displayLabel = (
30
+ <>
31
+ {label}
32
+ {isRequired && <span className={styles.requiredAsterisk}>*</span>}
33
+ </>
34
+ );
35
+
36
+ return (
37
+ <>
38
+ {/* Field header with icon and description */}
39
+ <div className={styles.listingField__header}>
40
+ <div className={styles.listingField__icon}>
41
+ <FontAwesomeIcon icon={iconImports.alignLeft} />
42
+ </div>
43
+ <div className={styles.listingField__content}>
44
+ <h3 className={styles.listingField__title}>Description</h3>
45
+ <p className={styles.listingField__description}>
46
+ Longer text area for detailed information or stories
47
+ </p>
48
+ </div>
49
+ </div>
50
+
51
+ <GenericInput
52
+ type="textarea"
53
+ label={displayLabel}
54
+ placeholder={placeholder || ""}
55
+ value={value || ""}
56
+ onChange={handleChange}
57
+ isRequired={isRequired}
58
+ showError={!!showError}
59
+ errorMessage={errorMessage}
60
+ isValid={isValid()}
61
+ alwaysShowLabel
62
+ style={{ resize: "vertical" }}
63
+ />
64
+ {helpText && (
65
+ <div style={{ marginTop: "8px", color: "#6c7a90", fontSize: "14px" }}>
66
+ {helpText}
67
+ </div>
68
+ )}
69
+ </>
70
+ );
71
+ };
72
+
73
+ export default ListingDescriptionInput;
@@ -0,0 +1,101 @@
1
+ import React from "react";
2
+ import ListingTextInput from "./ListingTextInput.jsx";
3
+ import ListingDescriptionInput from "./ListingDescriptionInput.jsx";
4
+ import ListingImageInput from "./ListingImageInput.jsx";
5
+ import ListingGalleryInput from "./ListingGalleryInput.jsx";
6
+ import ListingCTAInput from "./ListingCTAInput.jsx";
7
+ import ListingFileInput from "./ListingFileInput.jsx";
8
+ import styles from "./ListingField.module.css";
9
+
10
+ const ListingField = ({
11
+ field,
12
+ value,
13
+ onChange,
14
+ showError,
15
+ errorMessage,
16
+ isActive,
17
+ }) => {
18
+ const fieldClassName =
19
+ showError || isActive
20
+ ? `${styles.listingField} ${styles.hasError}`
21
+ : styles.listingField;
22
+
23
+ const renderField = () => {
24
+ switch (field.type) {
25
+ case "title":
26
+ return (
27
+ <ListingTextInput
28
+ field={field}
29
+ value={value}
30
+ onChange={onChange}
31
+ showError={showError}
32
+ errorMessage={errorMessage}
33
+ />
34
+ );
35
+ case "description":
36
+ return (
37
+ <ListingDescriptionInput
38
+ field={field}
39
+ value={value}
40
+ onChange={onChange}
41
+ showError={showError}
42
+ errorMessage={errorMessage}
43
+ />
44
+ );
45
+ case "image":
46
+ case "feature-image":
47
+ return (
48
+ <ListingImageInput
49
+ field={field}
50
+ value={value}
51
+ onChange={onChange}
52
+ showError={showError}
53
+ errorMessage={errorMessage}
54
+ />
55
+ );
56
+ case "gallery":
57
+ return (
58
+ <ListingGalleryInput
59
+ field={field}
60
+ value={value}
61
+ onChange={onChange}
62
+ showError={showError}
63
+ errorMessage={errorMessage}
64
+ />
65
+ );
66
+ case "cta":
67
+ return (
68
+ <ListingCTAInput
69
+ field={field}
70
+ value={value}
71
+ onChange={onChange}
72
+ showError={showError}
73
+ errorMessage={errorMessage}
74
+ />
75
+ );
76
+ case "file":
77
+ return (
78
+ <ListingFileInput
79
+ field={field}
80
+ value={value}
81
+ onChange={onChange}
82
+ showError={showError}
83
+ errorMessage={errorMessage}
84
+ />
85
+ );
86
+ default:
87
+ return <div>Field type {field.type} not implemented</div>;
88
+ }
89
+ };
90
+
91
+ return (
92
+ <div className={fieldClassName} data-field-id={field.id}>
93
+ {renderField()}
94
+ {showError && errorMessage && (
95
+ <div className={styles.listingField__error}>{errorMessage}</div>
96
+ )}
97
+ </div>
98
+ );
99
+ };
100
+
101
+ export default ListingField;
@@ -0,0 +1,106 @@
1
+ /* Simple listing field styling - clean vertical layout */
2
+
3
+ .listingField {
4
+ padding: 0.5rem 0.8rem 0.6rem;
5
+ border-radius: var(--border-radius-xl);
6
+ background: var(--bg-white);
7
+ transition: box-shadow var(--transition-base) ease;
8
+ }
9
+
10
+ /* Field header with icon and description */
11
+ .listingField__header {
12
+ display: flex;
13
+ display: none;
14
+ align-items: flex-start;
15
+ gap: 0.3rem;
16
+
17
+ padding: 0 0.6rem 0.3rem;
18
+ border-bottom: 1px solid var(--border-line-grey);
19
+ margin: 0 calc(-1 * 0.7rem);
20
+ margin-bottom: 0.5rem;
21
+ }
22
+
23
+ .listingField__icon {
24
+ color: var(--text-bluegrey);
25
+ font-size: var(--font-size-base);
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .listingField__content {
30
+ flex: 1;
31
+ }
32
+
33
+ .listingField__title {
34
+ margin: 0 0 0.1rem 0;
35
+ font-weight: var(--font-weight-semibold);
36
+ font-size: var(--font-size-base);
37
+ color: var(--text-dark);
38
+ line-height: var(--line-height-snug);
39
+ }
40
+
41
+ .listingField__description {
42
+ margin: 0;
43
+ font-size: var(--font-size-xs);
44
+ color: var(--text-bluegrey);
45
+ line-height: var(--line-height-relaxed);
46
+ }
47
+
48
+ .listingField:last-child {
49
+ margin-bottom: 0;
50
+ }
51
+
52
+ /* Error state styling */
53
+ .listingField--error {
54
+ border-color: var(--colour-red);
55
+ }
56
+
57
+ /* Required field asterisk */
58
+ .requiredAsterisk {
59
+ color: var(--colour-red);
60
+ margin-left: 0.1rem;
61
+ font-weight: var(--font-weight-bold);
62
+ }
63
+
64
+ /* Error message styling */
65
+ .listingField__error {
66
+ margin-top: 0.1rem;
67
+ color: var(--colour-red);
68
+ font-size: var(--font-size-xs);
69
+ font-weight: var(--font-weight-normal);
70
+ line-height: var(--line-height-relaxed);
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 0.1rem;
74
+ }
75
+
76
+ .listingField__error::before {
77
+ content: "⚠";
78
+ font-size: var(--font-size-sm);
79
+ flex-shrink: 0;
80
+ }
81
+
82
+ /* Make error more visible */
83
+ .listingField.hasError {
84
+ position: relative;
85
+ }
86
+
87
+ .listingField.hasError input,
88
+ .listingField.hasError textarea,
89
+ .listingField.hasError select,
90
+ .listingField.hasError .genericInput,
91
+ .listingField.hasError .genericInput input,
92
+ .listingField.hasError .genericInput textarea,
93
+ .listingField.hasError .imageInputOuter-single,
94
+ .listingField.hasError .imageInputOuter-grid,
95
+ .listingField.hasError .FileInput,
96
+ .listingField.hasError .imageInput,
97
+ .listingField.hasError input[type="file"],
98
+ .listingField.hasError .file-input,
99
+ .listingField.hasError div[class*="imageInput"],
100
+ .listingField.hasError div[class*="file-input"],
101
+ .listingField.hasError .image-container,
102
+ .listingField.hasError .image-grid,
103
+ .listingField.hasError img {
104
+ }
105
+
106
+ /* Hover effect for better interactivity */
@@ -0,0 +1,255 @@
1
+ import React, { useRef, useState, useEffect } from "react";
2
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3
+ import { FileInput, Text, Button } from "../../components";
4
+ import { iconImports } from "../../components/iconImports.js";
5
+ import FileListItem from "./FileListItem.jsx";
6
+ import listingFieldStyles from "./ListingField.module.css";
7
+ import styles from "./ListingFileInput.module.css";
8
+
9
+ const ListingFileInput = ({
10
+ field,
11
+ value,
12
+ onChange,
13
+ showError,
14
+ errorMessage,
15
+ disabled = false,
16
+ }) => {
17
+ const fileInputRef = useRef(null);
18
+ const [internalFiles, setInternalFiles] = useState([]);
19
+
20
+ // Normalize file data to enhanced structure - always handle as multiple files
21
+ useEffect(() => {
22
+ if (value) {
23
+ // Handle multiple files - could be array of URLs or array of file objects
24
+ if (Array.isArray(value)) {
25
+ const normalizedFiles = value
26
+ .map((file) => {
27
+ if (typeof file === "string") {
28
+ // Backward compatibility: array of URLs
29
+ const fileName = file.split("/").pop() || "Unknown File";
30
+ return {
31
+ url: file,
32
+ name: fileName.replace(/\.[^/.]+$/, ""), // Remove extension
33
+ originalName: fileName,
34
+ uploading: false,
35
+ };
36
+ } else if (file && typeof file === "object" && file.url) {
37
+ // Enhanced structure
38
+ return {
39
+ url: file.url,
40
+ name: file.name || file.originalName || "Unknown File",
41
+ originalName:
42
+ file.originalName ||
43
+ file.url.split("/").pop() ||
44
+ "Unknown File",
45
+ uploading: false,
46
+ };
47
+ }
48
+ return null;
49
+ })
50
+ .filter(Boolean);
51
+ setInternalFiles(normalizedFiles);
52
+ } else {
53
+ // Handle single file values - normalize to array
54
+ let singleFile = null;
55
+ if (typeof value === "string") {
56
+ // Backward compatibility: single URL
57
+ const fileName = value.split("/").pop() || "Unknown File";
58
+ singleFile = {
59
+ url: value,
60
+ name: fileName.replace(/\.[^/.]+$/, ""),
61
+ originalName: fileName,
62
+ uploading: false,
63
+ };
64
+ } else if (value && typeof value === "object" && value.url) {
65
+ // Enhanced structure - preserve empty name if explicitly set
66
+ singleFile = {
67
+ url: value.url,
68
+ name:
69
+ value.name !== undefined
70
+ ? value.name
71
+ : value.originalName || "Unknown File",
72
+ originalName:
73
+ value.originalName ||
74
+ value.url.split("/").pop() ||
75
+ "Unknown File",
76
+ uploading: false,
77
+ };
78
+ }
79
+ setInternalFiles(singleFile ? [singleFile] : []);
80
+ }
81
+ } else {
82
+ setInternalFiles([]);
83
+ }
84
+ }, [value]);
85
+
86
+ // Handle new file upload from FileInput component
87
+ const handleFileUpload = (uploadedUrl) => {
88
+ // Handle case where uploadedUrl might be undefined
89
+ if (!uploadedUrl) {
90
+ return;
91
+ }
92
+
93
+ const fileName = uploadedUrl.split("/").pop() || "Unknown File";
94
+ const newFile = {
95
+ url: uploadedUrl,
96
+ name: "", // Start with empty name as requested
97
+ originalName: fileName,
98
+ uploading: false,
99
+ };
100
+
101
+ // Always add new file to existing array for multiple file support
102
+ const updatedFiles = [...internalFiles, newFile];
103
+ setInternalFiles(updatedFiles);
104
+ notifyParent(updatedFiles);
105
+ };
106
+
107
+ // Handle file name change
108
+ const handleNameChange = (url, newName) => {
109
+ const updatedFiles = internalFiles.map((file) =>
110
+ file.url === url ? { ...file, name: newName } : file,
111
+ );
112
+ setInternalFiles(updatedFiles);
113
+ notifyParent(updatedFiles);
114
+ };
115
+
116
+ // Handle file removal
117
+ const handleFileRemove = (url) => {
118
+ const updatedFiles = internalFiles.filter((file) => file.url !== url);
119
+ setInternalFiles(updatedFiles);
120
+ notifyParent(updatedFiles);
121
+ };
122
+
123
+ // Notify parent component of changes
124
+ const notifyParent = (files) => {
125
+ if (onChange) {
126
+ // Always return array of files for multiple file support
127
+ onChange(field.id, files);
128
+ }
129
+ };
130
+
131
+ // Define acceptable file types for documents and common formats
132
+ const acceptTypes = {
133
+ "application/pdf": [".pdf"],
134
+ "application/msword": [".doc"],
135
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": [
136
+ ".docx",
137
+ ],
138
+ "application/vnd.ms-excel": [".xls"],
139
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [
140
+ ".xlsx",
141
+ ],
142
+ "text/plain": [".txt"],
143
+ "text/csv": [".csv"],
144
+ "image/jpeg": [".jpg", ".jpeg"],
145
+ "image/png": [".png"],
146
+ };
147
+
148
+ // Always show drop zone regardless of existing files
149
+
150
+ return (
151
+ <div className={styles.listingFileInput}>
152
+ {/* Field header with icon and description */}
153
+ <div className={listingFieldStyles.listingField__header}>
154
+ <div className={listingFieldStyles.listingField__icon}>
155
+ <FontAwesomeIcon icon={iconImports.file} />
156
+ </div>
157
+ <div className={listingFieldStyles.listingField__content}>
158
+ <h3 className={listingFieldStyles.listingField__title}>File</h3>
159
+ <p className={listingFieldStyles.listingField__description}>
160
+ Attach documents, PDFs, or other files
161
+ </p>
162
+ </div>
163
+ </div>
164
+
165
+ <Text type="formLabel" style={{ display: "block", marginBottom: "8px" }}>
166
+ {field.values.label}
167
+ {field.values.isRequired && (
168
+ <span className={listingFieldStyles.requiredAsterisk}>*</span>
169
+ )}
170
+ </Text>
171
+
172
+ {/* Drop zone */}
173
+ <div
174
+ className={`${styles.listingFileInput__dropZone} ${showError ? styles["listingFileInput__dropZone--error"] : ""}`}
175
+ >
176
+ <FileInput
177
+ ref={fileInputRef}
178
+ className="imageInputOuter-single"
179
+ refreshCallback={handleFileUpload}
180
+ hasDefault={null}
181
+ accept={acceptTypes}
182
+ multiple={false} // Always handle one file at a time in the upload callback
183
+ disabled={disabled}
184
+ />
185
+ </div>
186
+
187
+ {/* File list */}
188
+ {internalFiles.length > 0 && (
189
+ <div className={styles.listingFileInput__fileList}>
190
+ {internalFiles.map((file) => (
191
+ <FileListItem
192
+ key={file.url}
193
+ file={file}
194
+ onNameChange={handleNameChange}
195
+ onRemove={handleFileRemove}
196
+ disabled={disabled}
197
+ />
198
+ ))}
199
+ </div>
200
+ )}
201
+
202
+ {/* Add more files button - always show when files exist */}
203
+ {internalFiles.length > 0 && (
204
+ <div>
205
+ <FileInput
206
+ ref={fileInputRef}
207
+ className="imageInputOuter-single"
208
+ refreshCallback={handleFileUpload}
209
+ hasDefault={null}
210
+ accept={acceptTypes}
211
+ multiple={false}
212
+ disabled={disabled}
213
+ customButton={
214
+ <Button
215
+ buttonType="secondary"
216
+ className={styles.listingFileInput__addMoreButton}
217
+ disabled={disabled}
218
+ >
219
+ <FontAwesomeIcon icon={iconImports.plus} />
220
+ Add More Files
221
+ </Button>
222
+ }
223
+ />
224
+ </div>
225
+ )}
226
+
227
+ {showError && errorMessage && (
228
+ <Text
229
+ type="help"
230
+ style={{
231
+ color: "var(--colour-red)",
232
+ marginTop: "8px",
233
+ display: "block",
234
+ }}
235
+ >
236
+ {errorMessage}
237
+ </Text>
238
+ )}
239
+ {field.values.helpText && (
240
+ <Text
241
+ type="help"
242
+ style={{
243
+ color: "var(--text-bluegrey)",
244
+ marginTop: "8px",
245
+ display: "block",
246
+ }}
247
+ >
248
+ {field.values.helpText}
249
+ </Text>
250
+ )}
251
+ </div>
252
+ );
253
+ };
254
+
255
+ export default ListingFileInput;