@pareto-engineering/design-system 4.2.1 → 4.2.3

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 (55) hide show
  1. package/dist/cjs/f/FormInput/FormInput.js +6 -0
  2. package/dist/cjs/f/common/utils/index.js +8 -1
  3. package/dist/cjs/f/common/utils/validators.js +17 -0
  4. package/dist/cjs/f/fields/ChoicesInput/common/Choice/Choice.js +3 -2
  5. package/dist/cjs/f/fields/FileUpload/FileUpload.js +228 -0
  6. package/dist/cjs/f/fields/FileUpload/common/FilePreview/FilePreview.js +90 -0
  7. package/dist/cjs/f/fields/FileUpload/common/FilePreview/index.js +13 -0
  8. package/dist/cjs/f/fields/FileUpload/common/FilePreview/styles.scss +92 -0
  9. package/dist/cjs/f/fields/FileUpload/common/index.js +12 -0
  10. package/dist/cjs/f/fields/FileUpload/fileUploadOptions.js +31 -0
  11. package/dist/cjs/f/fields/FileUpload/index.js +20 -0
  12. package/dist/cjs/f/fields/FileUpload/styles.scss +73 -0
  13. package/dist/cjs/f/fields/index.js +14 -1
  14. package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +34 -7
  15. package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +11 -0
  16. package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +9 -3
  17. package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +2 -2
  18. package/dist/es/f/FormInput/FormInput.js +7 -1
  19. package/dist/es/f/common/utils/index.js +2 -1
  20. package/dist/es/f/common/utils/validators.js +10 -0
  21. package/dist/es/f/fields/ChoicesInput/common/Choice/Choice.js +3 -2
  22. package/dist/es/f/fields/FileUpload/FileUpload.js +218 -0
  23. package/dist/es/f/fields/FileUpload/common/FilePreview/FilePreview.js +80 -0
  24. package/dist/es/f/fields/FileUpload/common/FilePreview/index.js +2 -0
  25. package/dist/es/f/fields/FileUpload/common/FilePreview/styles.scss +92 -0
  26. package/dist/es/f/fields/FileUpload/common/index.js +2 -0
  27. package/dist/es/f/fields/FileUpload/fileUploadOptions.js +25 -0
  28. package/dist/es/f/fields/FileUpload/index.js +3 -0
  29. package/dist/es/f/fields/FileUpload/styles.scss +73 -0
  30. package/dist/es/f/fields/index.js +2 -1
  31. package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +35 -8
  32. package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +11 -0
  33. package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +9 -3
  34. package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +2 -1
  35. package/package.json +3 -3
  36. package/src/stories/f/FileUpload.stories.jsx +55 -0
  37. package/src/stories/g/FormBuilder.stories.jsx +19 -97
  38. package/src/ui/f/FormInput/FormInput.jsx +11 -0
  39. package/src/ui/f/common/utils/index.js +1 -0
  40. package/src/ui/f/common/utils/validators.js +10 -0
  41. package/src/ui/f/fields/ChoicesInput/common/Choice/Choice.jsx +2 -0
  42. package/src/ui/f/fields/FileUpload/FileUpload.jsx +277 -0
  43. package/src/ui/f/fields/FileUpload/common/FilePreview/FilePreview.jsx +115 -0
  44. package/src/ui/f/fields/FileUpload/common/FilePreview/index.js +2 -0
  45. package/src/ui/f/fields/FileUpload/common/FilePreview/styles.scss +92 -0
  46. package/src/ui/f/fields/FileUpload/common/index.js +2 -0
  47. package/src/ui/f/fields/FileUpload/fileUploadOptions.js +32 -0
  48. package/src/ui/f/fields/FileUpload/index.js +3 -0
  49. package/src/ui/f/fields/FileUpload/styles.scss +73 -0
  50. package/src/ui/f/fields/index.js +1 -0
  51. package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +53 -11
  52. package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +11 -0
  53. package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +13 -3
  54. package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +7 -2
  55. package/tests/__snapshots__/Storyshots.test.js.snap +163 -159
@@ -22,6 +22,9 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
22
22
 
23
23
  const baseClassName = _exports.default.base;
24
24
  const componentClassName = 'input-builder';
25
+ const getToggleSwitchStyles = condition => condition ? {
26
+ '--slider-background-color': 'var(--disabled)'
27
+ } : {};
25
28
 
26
29
  /**
27
30
  * This is the component description.
@@ -45,11 +48,6 @@ const InputBuilder = _ref => {
45
48
  const handleToggleRequired = () => {
46
49
  setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.required`, !input?.required);
47
50
  };
48
- const toggleSwitchStyles = {
49
- ...(!input?.required ? {
50
- '--slider-background-color': 'var(--disabled)'
51
- } : {})
52
- };
53
51
  const [hasDescription, setHasDescription] = (0, _react.useState)(false);
54
52
 
55
53
  // TODO: handle nav logic
@@ -69,6 +67,10 @@ const InputBuilder = _ref => {
69
67
  } = e.target;
70
68
  setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.options.${optionIndex}.label`, value);
71
69
  };
70
+ const isFile = input?.type === 'file';
71
+ const handleToggleShowSpecificFileTypes = () => {
72
+ setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.showSpecificFileTypes`, !input.showSpecificFileTypes);
73
+ };
72
74
  return /*#__PURE__*/React.createElement("div", {
73
75
  id: id,
74
76
  className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
@@ -102,6 +104,9 @@ const InputBuilder = _ref => {
102
104
  }, {
103
105
  value: 'choices',
104
106
  label: 'Radio buttons'
107
+ }, {
108
+ value: 'file',
109
+ label: 'File upload'
105
110
  }]
106
111
  }), /*#__PURE__*/React.createElement("div", {
107
112
  className: "controls"
@@ -117,7 +122,7 @@ const InputBuilder = _ref => {
117
122
  }, "Required"), /*#__PURE__*/React.createElement(_a.ToggleSwitch, {
118
123
  handleOnChange: handleToggleRequired,
119
124
  checked: input?.required,
120
- style: toggleSwitchStyles,
125
+ style: getToggleSwitchStyles(!input?.required),
121
126
  inputId: `sections_${sectionIndex}_inputs.${inputIndex}_toggle`
122
127
  })), /*#__PURE__*/React.createElement(_ActionsContainer.ActionsContainer, null, /*#__PURE__*/React.createElement("p", null, "Show"), /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", {
123
128
  className: `option ${hasDescription ? 'with-check-mark' : ''}`
@@ -181,7 +186,29 @@ const InputBuilder = _ref => {
181
186
  }, "+")), /*#__PURE__*/React.createElement("span", {
182
187
  className: "text x-paragraph c-x"
183
188
  }, "Add Option")));
184
- })));
189
+ }), isFile && /*#__PURE__*/React.createElement("div", {
190
+ className: "input-file-options"
191
+ }, /*#__PURE__*/React.createElement(_f.TextInput, {
192
+ label: "Maximum number of files",
193
+ name: `sections.${sectionIndex}.inputs.${inputIndex}.maxCount`,
194
+ placeholder: "1",
195
+ type: "number",
196
+ min: "0",
197
+ validate: _f.integerAndGreaterThanZero
198
+ }), /*#__PURE__*/React.createElement("div", {
199
+ className: "specific-file-types"
200
+ }, /*#__PURE__*/React.createElement(_a.ToggleSwitch, {
201
+ handleOnChange: handleToggleShowSpecificFileTypes,
202
+ checked: input?.showSpecificFileTypes,
203
+ style: getToggleSwitchStyles(!input?.showSpecificFileTypes),
204
+ inputId: `sections_${sectionIndex}_inputs.${inputIndex}_show_specific_file_types`
205
+ }), /*#__PURE__*/React.createElement("span", {
206
+ className: "s0"
207
+ }, "Allow only specific file types")), input?.showSpecificFileTypes && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_f.ChoicesInput, {
208
+ name: `sections.${sectionIndex}.inputs.${inputIndex}.accept`,
209
+ options: _f.fileUploadOptions,
210
+ multiple: true
211
+ })))));
185
212
  };
186
213
  InputBuilder.propTypes = {
187
214
  /**
@@ -137,6 +137,17 @@ $default-list-width: var(--action-button-width, 18rem);
137
137
  }
138
138
  }
139
139
  }
140
+
141
+ > .input-file-options {
142
+ display: flex;
143
+ flex-direction: column;
144
+ gap: var(--gap);
145
+ margin-bottom: $default-margin;
146
+
147
+ > .specific-file-types {
148
+ display: flex;
149
+ }
150
+ }
140
151
  }
141
152
  }
142
153
 
@@ -22,9 +22,14 @@ const reconstructFormDataWithValues = (formData, values) => {
22
22
  const newData = {
23
23
  ...formData
24
24
  };
25
- Object.keys(values).forEach(key => {
25
+ Object.keys(values).forEach(async key => {
26
26
  const [sectionIdx, inputIdx] = key.match(/\d+/g).map(Number);
27
- newData.sections[sectionIdx].inputs[inputIdx].value = values[key];
27
+ if (key.includes('files')) {
28
+ const files = values[key].map(file => URL.createObjectURL(file));
29
+ newData.sections[sectionIdx].inputs[inputIdx].files = files;
30
+ } else {
31
+ newData.sections[sectionIdx].inputs[inputIdx].value = values[key];
32
+ }
28
33
  });
29
34
  return newData;
30
35
  };
@@ -125,7 +130,8 @@ const Renderer = _ref => {
125
130
  return /*#__PURE__*/React.createElement(_formik.Form, null, updatedFormData.sections.map((section, sectionIndex) => sectionIndex === currentSectionIndex && /*#__PURE__*/React.createElement(_common.Section, _extends({
126
131
  key: `${section.title}`
127
132
  }, section, {
128
- readOnly: readOnly
133
+ readOnly: readOnly,
134
+ setUpdatedFormData: setUpdatedFormData
129
135
  }))), /*#__PURE__*/React.createElement("div", {
130
136
  className: "navigator-container"
131
137
  }, /*#__PURE__*/React.createElement(_b.Button, {
@@ -12,7 +12,7 @@ var _exports = _interopRequireDefault(require("@pareto-engineering/bem/exports")
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
14
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* @pareto-engineering/generator-front 1.1.1-alpha.2 */ // Local Definitions
15
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* eslint-disable no-alert */ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */ // Local Definitions
16
16
  const baseClassName = _exports.default.base;
17
17
  const componentClassName = 'section';
18
18
 
@@ -39,7 +39,7 @@ const Section = _ref => {
39
39
  }, title), /*#__PURE__*/React.createElement(_.ExpandableLexicalPreview, {
40
40
  nodes: description,
41
41
  name: "instructions"
42
- }), inputs.map(input => /*#__PURE__*/React.createElement(_f.FormInput, _extends({
42
+ }), inputs?.map(input => /*#__PURE__*/React.createElement(_f.FormInput, _extends({
43
43
  key: input.name
44
44
  }, input, {
45
45
  disabled: readOnly
@@ -3,7 +3,7 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
3
3
  import * as React from 'react';
4
4
  import { memo } from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import { TextInput, TextareaInput, ChoicesInput, SelectInput, QueryCombobox, QuerySelect, RatingsInput, Checkbox, QueryChoices, LinkInput, EditorInput } from "../fields";
6
+ import { TextInput, TextareaInput, ChoicesInput, SelectInput, QueryCombobox, QuerySelect, RatingsInput, Checkbox, QueryChoices, LinkInput, EditorInput, FileUpload } from "../fields";
7
7
  import "./styles.scss";
8
8
 
9
9
  // Local Definitions
@@ -89,6 +89,12 @@ const FormInput = ({
89
89
  disabled: disabled
90
90
  }, otherProps));
91
91
  }
92
+ if (type === 'file') {
93
+ return /*#__PURE__*/React.createElement(FileUpload, _extends({
94
+ className: newClassName,
95
+ disabled: disabled
96
+ }, otherProps));
97
+ }
92
98
  if (extraTypes?.[type]) {
93
99
  const Component = extraTypes[type];
94
100
  return /*#__PURE__*/React.createElement(Component, _extends({
@@ -1 +1,2 @@
1
- export { lookUpInputValueFromFetchedOptions } from "./lookUpInputValueFromFetchedOptions";
1
+ export { lookUpInputValueFromFetchedOptions } from "./lookUpInputValueFromFetchedOptions";
2
+ export { integerAndGreaterThanZero } from "./validators";
@@ -0,0 +1,10 @@
1
+ export const integerAndGreaterThanZero = value => {
2
+ let error = '';
3
+ if (value && value <= 0 || value === 0) {
4
+ error = 'Value must be greator than zero.';
5
+ }
6
+ if (value && value % 1 !== 0) {
7
+ error = 'You must enter a whole number.';
8
+ }
9
+ return error;
10
+ };
@@ -23,7 +23,8 @@ const Choice = ({
23
23
  value,
24
24
  multiple,
25
25
  validate,
26
- disabled
26
+ disabled,
27
+ ...otherProps
27
28
  }) => {
28
29
  const type = multiple ? 'checkbox' : 'radio';
29
30
  const [field] = useField({
@@ -39,7 +40,7 @@ const Choice = ({
39
40
  type: type,
40
41
  id: id,
41
42
  name: name
42
- }, field, {
43
+ }, field, otherProps, {
43
44
  value: value,
44
45
  disabled: disabled
45
46
  })), /*#__PURE__*/React.createElement("label", {
@@ -0,0 +1,218 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+ import * as React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { useField } from 'formik';
5
+ import styleNames from '@pareto-engineering/bem/exports';
6
+ import "./styles.scss";
7
+ import { FilePreview } from "./common";
8
+ import { FormLabel, FormDescription } from "../../common";
9
+
10
+ // Local Definitions
11
+
12
+ const baseClassName = styleNames.base;
13
+ const componentClassName = 'file-upload';
14
+
15
+ /**
16
+ * This is the component description.
17
+ */
18
+ const FileUpload = ({
19
+ id,
20
+ className: userClassName,
21
+ style,
22
+ label,
23
+ description,
24
+ accept,
25
+ multiple,
26
+ name,
27
+ disabled,
28
+ maxCount,
29
+ maxCountError,
30
+ maxSize,
31
+ maxSizeError,
32
+ onChange,
33
+ onDelete,
34
+ // TODO: TBD when connecting with BE
35
+ // onPreview,
36
+ // progress,
37
+ // percent,
38
+ // uploadStatus,
39
+ filePreviewAlignment,
40
+ optional,
41
+ labelColor,
42
+ color
43
+ // ...otherProps
44
+ }) => {
45
+ const [field,, helpers] = useField({
46
+ name
47
+ });
48
+ const {
49
+ value
50
+ } = field;
51
+ const {
52
+ setError,
53
+ setValue,
54
+ setTouched
55
+ } = helpers;
56
+ const handleChange = event => {
57
+ setTouched(true, false);
58
+ const newFiles = Array.from(event.currentTarget.files);
59
+ const currentFiles = value || [];
60
+ const currentCount = currentFiles.length + newFiles.length;
61
+ if (maxCount && currentCount > maxCount) {
62
+ setError(maxCountError || `Maximum of ${maxCount} files allowed`);
63
+ return;
64
+ }
65
+ const duplicateFiles = newFiles.filter(newFile => currentFiles.some(currentFile => currentFile.name === newFile.name));
66
+ if (duplicateFiles.length > 0) {
67
+ setError('You cannot upload the same file twice.');
68
+ return;
69
+ }
70
+ if (maxSize) {
71
+ const oversizedFiles = newFiles.filter(file => file.size > maxSize);
72
+ if (oversizedFiles.length > 0) {
73
+ setError(maxSizeError || `File size exceeds the limit of ${maxSize} bytes`);
74
+ return;
75
+ }
76
+ }
77
+ const updatedFiles = [...currentFiles, ...newFiles];
78
+ setValue(updatedFiles);
79
+ onChange?.(updatedFiles);
80
+
81
+ // eslint-disable-next-line no-param-reassign
82
+ event.target.value = null;
83
+ };
84
+ const handleDelete = fileIndex => {
85
+ const updatedFiles = value.filter((_, i) => i !== fileIndex);
86
+ setValue(updatedFiles);
87
+ onDelete?.(fileIndex);
88
+ };
89
+ const acceptOptions = Array.isArray(accept) ? accept?.join(',') : accept;
90
+ return /*#__PURE__*/React.createElement("div", {
91
+ id: id,
92
+ className: [baseClassName, componentClassName, userClassName, `preview-${filePreviewAlignment}`, `y-${color}`].filter(e => e).join(' '),
93
+ style: style
94
+ }, /*#__PURE__*/React.createElement("p", null, label), /*#__PURE__*/React.createElement(FormDescription, {
95
+ className: "s-1",
96
+ description: description,
97
+ name: name
98
+ }), !disabled && /*#__PURE__*/React.createElement(FormLabel, {
99
+ name: name,
100
+ color: labelColor,
101
+ optional: optional
102
+ }, /*#__PURE__*/React.createElement("input", {
103
+ id: name,
104
+ className: "file",
105
+ type: "file",
106
+ accept: acceptOptions,
107
+ multiple: multiple || maxCount && maxCount > 0,
108
+ disabled: disabled,
109
+ onChange: handleChange
110
+ }), /*#__PURE__*/React.createElement("span", {
111
+ className: "ai-icon"
112
+ }, "U"), /*#__PURE__*/React.createElement("span", null, "Attach file")), value?.length > 0 && /*#__PURE__*/React.createElement("div", {
113
+ className: "attached-files"
114
+ }, /*#__PURE__*/React.createElement("p", null, "Attached files:"), /*#__PURE__*/React.createElement("div", {
115
+ className: "files"
116
+ }, value.map((file, indx) => /*#__PURE__*/React.createElement(FilePreview, {
117
+ file: file,
118
+ key: file.name,
119
+ disabled: disabled,
120
+ handleDelete: () => handleDelete(indx)
121
+ })))));
122
+ };
123
+ FileUpload.propTypes = {
124
+ /**
125
+ * The HTML id for this element
126
+ */
127
+ id: PropTypes.string,
128
+ /**
129
+ * The HTML class names for this element
130
+ */
131
+ className: PropTypes.string,
132
+ /**
133
+ * The React-written, css properties for this element.
134
+ */
135
+ style: PropTypes.objectOf(PropTypes.string),
136
+ /**
137
+ * The label text for the file input
138
+ */
139
+ label: PropTypes.string,
140
+ /**
141
+ * The description text below the label
142
+ */
143
+ description: PropTypes.string,
144
+ /**
145
+ * The color of the text
146
+ */
147
+ color: PropTypes.string,
148
+ /**
149
+ * The accepted file types (e.g., 'image/*')
150
+ */
151
+ accept: PropTypes.string,
152
+ /**
153
+ * Whether to allow multiple file uploads
154
+ */
155
+ multiple: PropTypes.bool,
156
+ /**
157
+ * The name attribute for the input
158
+ */
159
+ name: PropTypes.string.isRequired,
160
+ /**
161
+ * Whether the the input should be disabled
162
+ */
163
+ disabled: PropTypes.bool,
164
+ /**
165
+ * The maximum number of files allowed
166
+ */
167
+ maxCount: PropTypes.number,
168
+ /**
169
+ * The error message when max count is exceeded
170
+ */
171
+ maxCountError: PropTypes.string,
172
+ /**
173
+ * The maximum size of files allowed (in bytes)
174
+ */
175
+ maxSize: PropTypes.number,
176
+ /**
177
+ * The error message when file size exceeds max size
178
+ */
179
+ maxSizeError: PropTypes.string,
180
+ /**
181
+ * The upload progress value (0-100)
182
+ */
183
+ // progress:PropTypes.number,
184
+
185
+ /**
186
+ * The function to handle file change events
187
+ */
188
+ onChange: PropTypes.func,
189
+ /**
190
+ * The function to handle file delete events
191
+ */
192
+ onDelete: PropTypes.func,
193
+ /**
194
+ * The function to handle file download events
195
+ */
196
+ // onDownload:PropTypes.func,
197
+
198
+ /**
199
+ * The function to handle file preview events
200
+ */
201
+ // onPreview:PropTypes.func,
202
+
203
+ /**
204
+ * The upload status of the file if being sent to an external service (e.g., 'uploading', 'done')
205
+ */
206
+ // uploadStatus:PropTypes.oneOf(['uploading', 'done', 'failed']),
207
+
208
+ /**
209
+ * The alignment for file previews WRT the upload input
210
+ */
211
+ filePreviewAlignment: PropTypes.oneOf(['left', 'right', 'top', 'bottom'])
212
+ };
213
+ FileUpload.defaultProps = {
214
+ disabled: false,
215
+ color: 'paragraph',
216
+ filePreviewAlignment: 'bottom'
217
+ };
218
+ export default FileUpload;
@@ -0,0 +1,80 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+ import * as React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import styleNames from '@pareto-engineering/bem/exports';
5
+
6
+ // Local Definitions
7
+
8
+ import "./styles.scss";
9
+ import { ProgressBar } from "../../../../../a";
10
+ import { Button } from "../../../../../b";
11
+ import { fileUploadOptions } from "../../fileUploadOptions";
12
+ const baseClassName = styleNames.base;
13
+ const componentClassName = 'file-preview';
14
+ const getFileType = file => {
15
+ const mimeType = file.type;
16
+ const extension = file.name.split('.').pop().toLowerCase();
17
+ const fileType = fileUploadOptions.find(option => option.value.includes(mimeType) || option.value.includes(extension));
18
+ return fileType ? fileType.key : 'unknown';
19
+ };
20
+
21
+ /**
22
+ * This is the component description.
23
+ */
24
+ const FilePreview = ({
25
+ id,
26
+ className: userClassName,
27
+ style,
28
+ file,
29
+ disabled,
30
+ handleDelete
31
+ // ...otherProps
32
+ }) => {
33
+ const type = getFileType(file);
34
+ return /*#__PURE__*/React.createElement("div", {
35
+ id: id,
36
+ className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
37
+ style: style
38
+ }, /*#__PURE__*/React.createElement("div", {
39
+ className: "identity"
40
+ }, /*#__PURE__*/React.createElement("span", {
41
+ className: ['type', type.toLowerCase()].filter(e => e).join(' ')
42
+ }, type), /*#__PURE__*/React.createElement("span", {
43
+ title: file.name,
44
+ className: "name"
45
+ }, file.name), /*#__PURE__*/React.createElement(Button, {
46
+ isCompact: true,
47
+ isSimple: true,
48
+ onClick: handleDelete
49
+ }, /*#__PURE__*/React.createElement("span", {
50
+ className: "icon x-ui-icons c-x"
51
+ }, "Y"))), !disabled && /*#__PURE__*/React.createElement("div", {
52
+ className: "progress-status"
53
+ }, /*#__PURE__*/React.createElement("div", {
54
+ className: "status"
55
+ }, /*#__PURE__*/React.createElement("span", {
56
+ className: "icon"
57
+ }, "I"), /*#__PURE__*/React.createElement("span", null, "Uploaded")), /*#__PURE__*/React.createElement(ProgressBar, {
58
+ color: "green",
59
+ progress: 100,
60
+ height: "3px"
61
+ })));
62
+ };
63
+ FilePreview.propTypes = {
64
+ /**
65
+ * The HTML id for this element
66
+ */
67
+ id: PropTypes.string,
68
+ /**
69
+ * The HTML class names for this element
70
+ */
71
+ className: PropTypes.string,
72
+ /**
73
+ * The React-written, css properties for this element.
74
+ */
75
+ style: PropTypes.objectOf(PropTypes.string)
76
+ };
77
+ FilePreview.defaultProps = {
78
+ // someProp:false
79
+ };
80
+ export default FilePreview;
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+ export { default as FilePreview } from "./FilePreview";
@@ -0,0 +1,92 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+
3
+ @use "@pareto-engineering/bem";
4
+
5
+ $default-padding: 1rem;
6
+ $files-per-row: 3;
7
+ $total-gaps: $files-per-row - 1;
8
+ $combined-gap: calc(var(--gap) * $total-gaps);
9
+ $width-without-gaps: calc(100% - $combined-gap);
10
+ $default-file-width: calc($width-without-gaps / $files-per-row);
11
+
12
+ .#{bem.$base}.file-preview {
13
+ border: var(--theme-default-border-style) var(--ui-lines);
14
+ border-radius: calc(var(--theme-default-border-radius) / 2);
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: calc(var(--gap) / 4);
18
+ padding: $default-padding;
19
+ width: $default-file-width;
20
+
21
+ > .identity {
22
+ align-items: center;
23
+ display: flex;
24
+ gap: calc(var(--gap) / 2);
25
+
26
+ > .type {
27
+ padding-block: calc($default-padding / 4);
28
+ padding-inline: calc($default-padding / 2);
29
+
30
+ // TODO: update the colors to use variables. These are colors from the new DS
31
+ &.pdf {
32
+ background-color: #fdead7;
33
+ color: #b93814;
34
+ }
35
+
36
+ &.file {
37
+ background-color: #eef2f6;
38
+ color: #364151;
39
+ }
40
+
41
+ &.txt {
42
+ background-color: #d1dfff;
43
+ color: #004eeb;
44
+ }
45
+
46
+
47
+ &.vid {
48
+ background-color: #ebe9fe;
49
+ color: #5a25dc;
50
+ }
51
+
52
+ &.img {
53
+ background-color: #cbfbef;
54
+ color: #107569;
55
+ }
56
+
57
+ &.aud {
58
+ background-color: #fef7c3;
59
+ color: #a15c08;
60
+ }
61
+ }
62
+
63
+ > .name {
64
+ overflow: hidden;
65
+ text-overflow: ellipsis;
66
+ white-space: nowrap;
67
+ }
68
+
69
+ > .#{bem.$base}.button {
70
+ cursor: pointer;
71
+ margin-left: auto;
72
+ }
73
+ }
74
+
75
+ > .progress-status {
76
+ > .status {
77
+ align-items: center;
78
+ // TODO handle as a prop
79
+ color: var(--green);
80
+ display: flex;
81
+ gap: calc(var(--gap) / 2);
82
+
83
+ > .icon {
84
+ background-color: var(--green);
85
+ border-radius: 50%;
86
+ color: var(--on-green);
87
+ font-size: calc(var(--s-2) * 1rem);
88
+ padding: calc($default-padding / 4);
89
+ }
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+ export { FilePreview } from "./FilePreview";
@@ -0,0 +1,25 @@
1
+ export const fileUploadOptions = [{
2
+ key: 'FILE',
3
+ value: '.doc,.docx,.odt,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.oasis.opendocument.text',
4
+ label: 'Documents'
5
+ }, {
6
+ key: 'TXT',
7
+ value: '.xls,.xlsx,.ods,.csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet,text/csv',
8
+ label: 'Spreadsheets'
9
+ }, {
10
+ key: 'PDF',
11
+ value: '.pdf,application/pdf',
12
+ label: 'PDF'
13
+ }, {
14
+ key: 'VID',
15
+ value: '.mp4,.ogg,.webm,video/mp4,video/ogg,video/webm',
16
+ label: 'Videos'
17
+ }, {
18
+ key: 'IMG',
19
+ value: '.png,.jpeg,.jpg,.gif,.webp,image/png,image/jpeg,image/gif,image/webp',
20
+ label: 'Images'
21
+ }, {
22
+ key: 'AUD',
23
+ value: '.mp3,.ogg,.wav,audio/mpeg,audio/ogg,audio/wav',
24
+ label: 'Audio'
25
+ }];
@@ -0,0 +1,3 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+ export { default as FileUpload } from "./FileUpload";
3
+ export { fileUploadOptions } from "./fileUploadOptions";