@startlibs/form 1.0.12 → 1.1.1

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 (92) hide show
  1. package/lib/AutoComplete.mjs +550 -0
  2. package/lib/AutoComplete.mjs.map +1 -0
  3. package/lib/Checkbox.mjs +76 -0
  4. package/lib/Checkbox.mjs.map +1 -0
  5. package/lib/Combobox.mjs +544 -0
  6. package/lib/Combobox.mjs.map +1 -0
  7. package/lib/ComboboxWithCustom.mjs +77 -0
  8. package/lib/ComboboxWithCustom.mjs.map +1 -0
  9. package/lib/DatePicker.mjs +625 -0
  10. package/lib/DatePicker.mjs.map +1 -0
  11. package/lib/EditableBox.mjs +496 -0
  12. package/lib/EditableBox.mjs.map +1 -0
  13. package/lib/Errors.mjs +176 -0
  14. package/lib/Errors.mjs.map +1 -0
  15. package/lib/ExpandableBox.mjs +209 -0
  16. package/lib/ExpandableBox.mjs.map +1 -0
  17. package/lib/Field.mjs +65 -0
  18. package/lib/Field.mjs.map +1 -0
  19. package/lib/FieldBox.mjs +80 -0
  20. package/lib/FieldBox.mjs.map +1 -0
  21. package/lib/Form.mjs +322 -0
  22. package/lib/Form.mjs.map +1 -0
  23. package/lib/FormValue.mjs +111 -0
  24. package/lib/FormValue.mjs.map +1 -0
  25. package/lib/InputboxGroup.mjs +104 -0
  26. package/lib/InputboxGroup.mjs.map +1 -0
  27. package/lib/Radiobox.mjs +67 -0
  28. package/lib/Radiobox.mjs.map +1 -0
  29. package/lib/RichText.mjs +634 -0
  30. package/lib/RichText.mjs.map +1 -0
  31. package/lib/TextInput.mjs +359 -0
  32. package/lib/TextInput.mjs.map +1 -0
  33. package/lib/alt/checkbox/SimpleCheckbox.mjs +82 -0
  34. package/lib/alt/checkbox/SimpleCheckbox.mjs.map +1 -0
  35. package/lib/alt/checkbox/ToggleCheckbox.mjs +68 -0
  36. package/lib/alt/checkbox/ToggleCheckbox.mjs.map +1 -0
  37. package/lib/alt/radiobox/CleanTabRadiobox.mjs +44 -0
  38. package/lib/alt/radiobox/CleanTabRadiobox.mjs.map +1 -0
  39. package/lib/alt/radiobox/IconRadioBox.mjs +52 -0
  40. package/lib/alt/radiobox/IconRadioBox.mjs.map +1 -0
  41. package/lib/alt/radiobox/SimpleRadiobox.mjs +61 -0
  42. package/lib/alt/radiobox/SimpleRadiobox.mjs.map +1 -0
  43. package/lib/alt/radiobox/TabRadiobox.mjs +54 -0
  44. package/lib/alt/radiobox/TabRadiobox.mjs.map +1 -0
  45. package/lib/enhanceInput.mjs +131 -0
  46. package/lib/enhanceInput.mjs.map +1 -0
  47. package/lib/index.cjs +5345 -0
  48. package/lib/index.cjs.map +1 -0
  49. package/lib/index.mjs +28 -0
  50. package/lib/index.mjs.map +1 -0
  51. package/lib/useConfirmDialog.mjs +117 -0
  52. package/lib/useConfirmDialog.mjs.map +1 -0
  53. package/lib/useDraftConfirmation.mjs +56 -0
  54. package/lib/useDraftConfirmation.mjs.map +1 -0
  55. package/lib/validation.mjs +91 -0
  56. package/lib/validation.mjs.map +1 -0
  57. package/lib/withFormImageInput.mjs +281 -0
  58. package/lib/withFormImageInput.mjs.map +1 -0
  59. package/package.json +46 -26
  60. package/src/AutoComplete.jsx +642 -0
  61. package/src/Checkbox.jsx +45 -0
  62. package/src/Combobox.jsx +606 -0
  63. package/src/ComboboxWithCustom.jsx +68 -0
  64. package/src/DatePicker.jsx +733 -0
  65. package/src/EditableBox.jsx +502 -0
  66. package/src/Errors.jsx +174 -0
  67. package/src/ExpandableBox.jsx +207 -0
  68. package/src/Field.jsx +76 -0
  69. package/src/FieldBox.jsx +136 -0
  70. package/src/Form.jsx +291 -0
  71. package/src/FormValue.jsx +67 -0
  72. package/src/IconRadioBoxOldHubt.jsx +93 -0
  73. package/src/InputboxGroup.jsx +121 -0
  74. package/src/Radiobox.jsx +33 -0
  75. package/src/RichText.jsx +812 -0
  76. package/src/TextInput.jsx +519 -0
  77. package/src/alt/checkbox/SimpleCheckbox.jsx +162 -0
  78. package/src/alt/checkbox/ToggleCheckbox.jsx +143 -0
  79. package/src/alt/radiobox/CleanTabRadiobox.jsx +46 -0
  80. package/src/alt/radiobox/IconRadioBox.jsx +93 -0
  81. package/src/alt/radiobox/SimpleRadiobox.jsx +153 -0
  82. package/src/alt/radiobox/TabRadiobox.jsx +73 -0
  83. package/src/enhanceInput.jsx +107 -0
  84. package/src/index.js +27 -0
  85. package/src/useConfirmDialog.jsx +105 -0
  86. package/src/useDraftConfirmation.jsx +60 -0
  87. package/src/validation.js +92 -0
  88. package/src/withFormImageInput.jsx +297 -0
  89. package/.babelrc +0 -28
  90. package/lib/index.js +0 -6258
  91. package/rollup.config.js +0 -43
  92. package/yarn-error.log +0 -1607
@@ -0,0 +1,105 @@
1
+ import React from 'react'
2
+ import _ from 'lodash/fp'
3
+ import {Errors} from './Errors'
4
+ import {WithForm} from './Form'
5
+ import {callIfFunction, addExtraProp, using} from '@startlibs/utils'
6
+ import {setNotification, Button, Dialog} from '@startlibs/components'
7
+ import {useDialogWithToggle, useDialog} from '@startlibs/components'
8
+
9
+ export const useConfirmDialog = (dialog, args, toggleCallback) => {
10
+ return useDialog((closeDialog) => addExtraProp(callIfFunction(dialog, closeDialog), {closeDialog}), args, toggleCallback)
11
+ }
12
+
13
+ export const useConfirmDialogWithProps = (dialog, args, {overrideClose = true} = {}) => {
14
+ return useDialogWithToggle((toggle) => addExtraProp(callIfFunction(dialog, toggle.isOpen, toggle.close), {closeDialog: toggle.close}, overrideClose), args)
15
+ }
16
+
17
+ export const ConfirmDialog = ({
18
+ action = _.identity,
19
+ onSuccess,
20
+ skipDom,
21
+ className,
22
+ closeDialog,
23
+ onClose,
24
+ skipCloseIcon,
25
+ cancelLabel = "Cancelar",
26
+ cancelButton = cancelLabel && <Button tabIndex={2}>{cancelLabel}</Button>,
27
+ onFailure,
28
+ title,
29
+ keepOnSuccess,
30
+ confirm,
31
+ formRef,
32
+ children,
33
+ preValidation,
34
+ onNonPreValidation,
35
+ values,meta,
36
+ onChange,
37
+ alternativeButton,
38
+ notify,
39
+ confirmChanges,
40
+ auxiliarActions,
41
+ transform,
42
+ isLoading,
43
+ stickyFooter,
44
+ fullscreen,
45
+ fullscreenOnMobile,
46
+ alwaysSave = true,skipErrors,
47
+ hidden,
48
+ skipCheckFocus
49
+ }) => {
50
+ const handleClose = React.useCallback(async () => {
51
+ if (onClose) await onClose().catch(console.error)
52
+ if (closeDialog) closeDialog()
53
+ }, [onClose, closeDialog])
54
+
55
+ return <WithForm
56
+ alwaysSave={alwaysSave}
57
+ ref={formRef}
58
+ preValidation={preValidation}
59
+ onNonPreValidation={onNonPreValidation}
60
+ values={values}
61
+ meta={meta}
62
+ action={action}
63
+ transform={transform}
64
+ onFailure={onFailure}
65
+ onChange={onChange}
66
+ onSuccess={(...props) =>
67
+ Promise.resolve(callIfFunction(onSuccess, ...props))
68
+ .then((v) => {
69
+ if (!keepOnSuccess) {
70
+ handleClose()
71
+ }
72
+ if (notify) {
73
+ setNotification(notify)
74
+ }
75
+ return v
76
+ })
77
+ }
78
+ >{form => !hidden &&
79
+ <Dialog
80
+ className={className}
81
+ title={title}
82
+ skipCheckFocus={skipCheckFocus}
83
+ skipCloseIcon={skipCloseIcon}
84
+ confirmChanges={confirmChanges}
85
+ isLoading={isLoading}
86
+ closeDialog={handleClose}
87
+ form={form}
88
+ stickyFooter={stickyFooter}
89
+ auxiliarActions={auxiliarActions}
90
+ fullscreen={fullscreen}
91
+ fullscreenOnMobile={fullscreenOnMobile}
92
+ footer={(cancelButton || alternativeButton || confirm) && <>
93
+ {cancelButton && addExtraProp(callIfFunction(cancelButton,handleClose),{onClick:handleClose},false)}
94
+ {callIfFunction(alternativeButton, handleClose)}
95
+ {confirm && using(callIfFunction(confirm,{form,isLoading}))( c => c && addExtraProp(c, {isLoading: form.isLoading, type: "submit"}))}
96
+ </>}
97
+ >
98
+ {callIfFunction(children,form)}
99
+ {!skipErrors && <Errors autoScroll/>}
100
+ </Dialog>
101
+ }</WithForm>
102
+ }
103
+
104
+
105
+ export const FormDialog = ConfirmDialog
@@ -0,0 +1,60 @@
1
+ import React, {useContext} from 'react'
2
+ import {useToggle, useRefToggle, StartlibsContext, useRefState} from '@startlibs/core'
3
+ import {callIfFunction} from '@startlibs/utils'
4
+
5
+ export const useDraftConfirmation = (submit, discard, meta) => {
6
+ const loading = useToggle()
7
+ const dialog = useToggle()
8
+ const draft = useRefToggle()
9
+ const promiseResolver = useRefState()
10
+ const startlibs = useContext(StartlibsContext)
11
+
12
+ const confirmation = (dialogType = 'submit-draft', callback) => {
13
+ if (callIfFunction(draft.isOpen)) {
14
+ dialog.openWith(dialogType)
15
+ return new Promise((res) =>
16
+ promiseResolver.set(() => (r) => {
17
+ dialog.close()
18
+ callIfFunction(callback,r)
19
+ res(r)
20
+ }))
21
+ } else {
22
+ return Promise.resolve()
23
+ }
24
+ }
25
+
26
+
27
+ const submitAndResolve = async () => {
28
+ loading.open()
29
+ try {
30
+ await submit()
31
+ callIfFunction(promiseResolver.get())
32
+ } catch (e) { } finally {
33
+ dialog.close()
34
+ loading.close()
35
+ }
36
+ }
37
+
38
+ const discardAndResolve = () => {
39
+ callIfFunction(discard)
40
+ callIfFunction(promiseResolver.get())
41
+ }
42
+
43
+ const Dialog = startlibs.dialogs[dialog.isOpen]
44
+ if (process.env.NODE_ENV !== 'production') {
45
+ if (dialog.isOpen && !Dialog) { console.log(`Dialog [${dialogType}] not registered in startlibs.dialogs`) }
46
+ }
47
+
48
+ const feedback =
49
+ dialog.isOpen
50
+ ? <Dialog
51
+ submit={submitAndResolve}
52
+ discard={discardAndResolve}
53
+ isLoading={loading.isOpen}
54
+ cancel={dialog.close}
55
+ {...meta}
56
+ />
57
+ : null
58
+
59
+ return [feedback, draft, confirmation]
60
+ }
@@ -0,0 +1,92 @@
1
+ import _ from 'lodash/fp'
2
+ import {callIfFunction} from '@startlibs/utils'
3
+
4
+ const error = 'Error'
5
+
6
+ let messages = {
7
+ required: error,
8
+ minLength: (n) => error,
9
+ confirmPassword: error,
10
+ confirmEmails: error,
11
+ emailValidation: error,
12
+ SERVER_ERROR: error
13
+ }
14
+
15
+ export let SERVER_ERROR = messages.SERVER_ERROR
16
+
17
+ export const setErrorMessages = (newMessages) => messages = newMessages
18
+
19
+ const onEmpty = (success, errors) => Object.keys(errors).length ? errors : success
20
+
21
+ export const required = (s, k) => !s && messages.required
22
+
23
+ export const minLength = (n) => (s, k) => s && s.length < n && messages.minLength(n)
24
+
25
+ export const confirmPasswords = (passwordKey) => (confirm, k, props) => (props[passwordKey] || confirm) && props[passwordKey] !== confirm && messages.confirmPassword
26
+ export const confirmEmails = (emailKey) => (confirm, k, props) => (props[emailKey] || confirm) && props[emailKey] !== confirm && messages.confirmEmails
27
+ export const confirm = (sourceKey,messageKey,isEqual = (a,b) => a === b) => (confirm, k, props) => (props[sourceKey] || confirm) && !isEqual(props[sourceKey],confirm) && (messages[messageKey] || messageKey)
28
+
29
+ const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i
30
+ export const emailValidation = (s, k) => !emailRegex.test(s) && messages.emailValidation
31
+
32
+ export const optional = (cb) => (v, ...args) => v ? cb(v, ...args) : false
33
+
34
+ export const buildValidation = (validations, custom = () => {
35
+ }) => (values) =>
36
+ onEmpty(false,
37
+ {
38
+ ..._.flow(
39
+ _.entries,
40
+ _.map(([k, v]) => [k, [].concat(v).map(fn => fn(_.get(k, values), k, values)).filter(_ => _)]),
41
+ _.filter(([k, v]) => v.length),
42
+ _.fromPairs
43
+ )(callIfFunction(validations)),
44
+ ...callIfFunction(custom, values)
45
+ }
46
+ )
47
+
48
+ export const buildAsyncValidation = (validations, custom = async () => {
49
+ }) => async (props) =>
50
+ onEmpty(false,
51
+ {
52
+ ... await _.flow(
53
+ _.entries,
54
+ _.map(([k, v]) => Promise.all([].concat(v).map(fn => fn(_.get(k, props), k, props))).then(v => [k,v.filter(Boolean)])),
55
+ promiseArray => Promise.all(promiseArray).then((v) =>
56
+ _.flow(
57
+ _.filter(([k, v]) => v.length),
58
+ _.fromPairs
59
+ )(v)
60
+ )
61
+ )(await callIfFunction(validations)),
62
+ ... await callIfFunction(custom, props)
63
+ }
64
+ )
65
+
66
+
67
+ export const responseFailure = (fn) => (v, response, {setErrors}) => {
68
+ const errorSetter = setErrors
69
+ const r = [].concat(response, v)
70
+ const error = fn(...r)
71
+ if (error === true) {
72
+ } else if (error) {
73
+ errorSetter(error)
74
+ } else if (!_.get('[0].errors',response)) {
75
+ errorSetter({"": [messages.SERVER_ERROR]})
76
+ }
77
+ }
78
+
79
+ export const validation = {
80
+ SERVER_ERROR,
81
+ setErrorMessages,
82
+ required,
83
+ minLength,
84
+ confirmPasswords,
85
+ confirmEmails,
86
+ confirm,
87
+ emailValidation,
88
+ optional,
89
+ buildValidation,
90
+ buildAsyncValidation,
91
+ responseFailure
92
+ }
@@ -0,0 +1,297 @@
1
+ import React, {useContext, useState} from 'react'
2
+ import styled from 'styled-components'
3
+ import {FormContext, useFormValue} from './Form'
4
+ import {useToggle} from '@startlibs/core'
5
+ import {getUID, callIfFunction} from '@startlibs/utils'
6
+ import _ from 'lodash/fp'
7
+
8
+ export const FileInput = styled.input.attrs({type: 'file'})`
9
+ z-index: 1;
10
+ cursor: pointer;
11
+ opacity: 0;
12
+ position: absolute;
13
+ top: 0;
14
+ right: 0;
15
+ left: 0;
16
+ bottom: 0;
17
+ width: 100%;
18
+ height: 100%;
19
+ overflow: hidden;
20
+ ::-webkit-file-upload-button {
21
+ visibility: hidden;
22
+ }
23
+ ::file-upload-button {
24
+ visibility: hidden;
25
+ }
26
+ `
27
+
28
+
29
+ export const WithImageInput = ({children, multiple, path = ["image"], preValidation = _.stubFalse, onChangeFile, onClose, onClick, uploadFetcher, onSuccess, onFailure, ajaxError, onTouchEnd, ...rest}) => {
30
+ const form = useContext(FormContext)
31
+ const loading = useToggle()
32
+ const [tempImage, setTempImage] = useState()
33
+ const getPath = (str,fileIndex = 0) => typeof path === 'function' ? [].concat(path(str,fileIndex)) : str !== 'image' ? [].concat(path).slice(0, -1).concat(str) : path
34
+
35
+ const imagePath = getPath('image')
36
+ const [formImage] = useFormValue(imagePath)
37
+ const image = tempImage || formImage
38
+
39
+ const validate = (files) => {
40
+ const validations = files.map(preValidation).filter(Boolean)
41
+ if (validations.length) {
42
+ validations.forEach(v =>
43
+ form.setError(getPath('image').join('.'), v)
44
+ )
45
+ return files.filter((file) => !preValidation(file))
46
+ }
47
+ return files
48
+ }
49
+
50
+ const handleFileEvent = (e) => {
51
+ e.preventDefault()
52
+ callIfFunction(onClose)
53
+ const files = Array.from((e.nativeEvent.dataTransfer || e.nativeEvent.target).files)
54
+ if (files.length > 0) {
55
+ validate(files.slice(0,multiple ? undefined : 1)).forEach( (file,i) =>
56
+ handleFile(file,e,i)
57
+ )
58
+ }
59
+ }
60
+
61
+ const handleFile = (file, eventTarget, fileIndex = 0) => {
62
+ const getIndexedPath = (str) => getPath(str,fileIndex)
63
+ const path = getIndexedPath()
64
+ const oldUploadStatus = form.getMeta(getIndexedPath('uploadStatus'))
65
+ const oldImage = form.getValue(getIndexedPath('image'))
66
+ const oldImageHeight = form.getValue(getIndexedPath('imageHeight'))
67
+ const oldImageWidth = form.getValue(getIndexedPath('imageWidth'))
68
+ const oldFilename = form.getValue(getIndexedPath('fileName'))
69
+
70
+ const objectUrl = URL.createObjectURL(file)
71
+ const image = document.createElement('img')
72
+ image.onload = () => {
73
+ const {naturalWidth: imageWidth, naturalHeight: imageHeight} = image
74
+ const newValues = {image: file, filename: file.name, imageWidth, imageHeight}
75
+ form.setValues(_.flow(
76
+ _.set(getIndexedPath('filename'), file.name),
77
+ _.set(getIndexedPath('image'), file),
78
+ _.set(getIndexedPath('imageWidth'), imageWidth),
79
+ _.set(getIndexedPath('imageHeight'), imageHeight)
80
+ ))
81
+ form.setMeta(_.flow(
82
+ _.update('submittingFiles', (v) => v ? v + 1 : 1),
83
+ _.update('uploadingPaths', _.union([path.join(".")])),
84
+ _.set(getIndexedPath('uploadStatus'), 'loading')
85
+ ))
86
+ setTempImage(objectUrl)
87
+ callIfFunction(onChangeFile,file)
88
+ loading.open()
89
+ uploadFetcher(file, newValues)
90
+ .then(({image, uploadStatus}) => {
91
+ loading.close()
92
+ if (form.getValue(getIndexedPath('image')) !== file) {
93
+ form.setMeta(_.update(['submittingFiles'], (v) => v - 1))
94
+ return
95
+ }
96
+ form.clearErrors()
97
+ form.setValue(getIndexedPath('image'), image, false)
98
+ form.setMeta(_.flow(
99
+ _.update('uploadingPaths', _.difference(_,[path.join(".")])),
100
+ _.update(['submittingFiles'], (v) => v - 1),
101
+ _.update(['submittedFiles'], (v) => (v || []).concat([{path, file, image}])),
102
+ _.set(getIndexedPath('uploadStatus'), uploadStatus)
103
+ ))
104
+ setTempImage(null)
105
+ callIfFunction(onSuccess, {image, uploadStatus, imageWidth, imageHeight})
106
+ }).catch((e) => {
107
+ loading.close()
108
+ if (form.getValue(getIndexedPath('image')) !== file) {
109
+ form.setMeta(_.update(['submittingFiles'], (v) => v - 1))
110
+ return
111
+ }
112
+ form.setError(getIndexedPath('image').join('.'), callIfFunction(ajaxError,_.get('[1].status',e)))
113
+ form.setValues(_.flow(
114
+ _.set(getIndexedPath('filename'), oldFilename),
115
+ _.set(getIndexedPath('image'), oldImage),
116
+ _.set(getIndexedPath('imageWidth'), oldImageWidth),
117
+ _.set(getIndexedPath('imageHeight'), oldImageHeight)
118
+ ),
119
+ false
120
+ )
121
+ form.setMeta(_.flow(
122
+ _.update('uploadingPaths', _.difference(_,[path.join(".")])),
123
+ _.update(['submittingFiles'], (v) => v - 1),
124
+ _.update(['submittedFiles'], (v) => (v || []).concat([{path, file, image}])),
125
+ _.set(getIndexedPath('uploadStatus'), oldUploadStatus)
126
+ ))
127
+ setTempImage(null)
128
+ callIfFunction(onFailure)
129
+ })
130
+ if (eventTarget && eventTarget.parentNode && typeof eventTarget.parentNode.click === 'function')
131
+ eventTarget.parentNode.click()
132
+ }
133
+ image.src = objectUrl
134
+ }
135
+
136
+ const listenToClose = () => {
137
+ }
138
+
139
+ const handleClick = (e) => {
140
+ callIfFunction(onClick,e)
141
+ listenToClose()
142
+ }
143
+ const handleTouchEnd = (e) => {
144
+ callIfFunction(onTouchEnd,e)
145
+ listenToClose()
146
+ }
147
+
148
+ return children(
149
+ <FileInput multiple={multiple} onChange={handleFileEvent} onClick={handleClick} tabIndex={-1} onTouchEnd={handleTouchEnd}/>,
150
+ {
151
+ image,
152
+ isLoading: loading.isOpen,
153
+ handleFile,
154
+ handleFileEvent,
155
+ Input: FileInput
156
+ }
157
+ )
158
+ }
159
+
160
+
161
+
162
+
163
+ export const WithFileInput = ({children, multiple, path = ["file"], preValidation = _.stubFalse, onChangeFile, onClose, onClick, uploadFetcher, onSuccess, onFailure, ajaxError, onTouchEnd, maxFiles, ...rest}) => {
164
+ const form = useContext(FormContext)
165
+ const loading = useToggle()
166
+ const [tempImage, setTempImage] = useState()
167
+ const getPath = (str,fileIndex) => typeof path === 'function' ? [].concat(path(str,fileIndex)) : str !== 'file' ? [].concat(path).slice(0, -1).concat(str) : path
168
+
169
+ const validate = (files) => {
170
+ const validations = files.map(preValidation).filter(Boolean)
171
+ if (validations.length) {
172
+ validations.forEach(v =>
173
+ form.setError(getPath('file',0).join('.'), v)
174
+ )
175
+ return files.filter((file) => !preValidation(file))
176
+ }
177
+ return files
178
+ }
179
+
180
+ const handleFileEvent = (e) => {
181
+ e.preventDefault()
182
+ callIfFunction(onClose)
183
+ const files = Array.from((e.nativeEvent.dataTransfer || e.nativeEvent.target).files)
184
+ if (files.length > 0) {
185
+ validate(files.slice(0,multiple ? undefined : 1)).forEach( (file,i) =>
186
+ handleFile(file,e,i)
187
+ )
188
+ }
189
+ }
190
+
191
+ const handleFile = (file, eventTarget) => {
192
+ const currentFileIndex = (form.getValue(getPath()) || []).length
193
+ if (currentFileIndex >= maxFiles) {
194
+ form.setErrors({'': 'Número máximo de arquivos atingido'})
195
+ return
196
+ }
197
+ const createGetIndexedPath = (index) => (str) => getPath(str,index)
198
+ const getIndexedPath = createGetIndexedPath(currentFileIndex)
199
+ const path = getIndexedPath()
200
+ const oldUploadStatus = form.getMeta(getIndexedPath('uploadStatus'))
201
+ const oldFile = form.getValue(getIndexedPath('file'))
202
+ const oldFilename = form.getValue(getIndexedPath('fileName'))
203
+
204
+ const uid = getUID()
205
+
206
+ form.setValues(_.flow(
207
+ _.set(getIndexedPath('filename'), file.name),
208
+ _.set(getIndexedPath('file'), file),
209
+ _.set(getIndexedPath('uid'), uid),
210
+ ))
211
+ form.setMeta(_.flow(
212
+ _.update('submittingFiles', (v) => v ? v + 1 : 1),
213
+ _.update('uploadingPaths', _.union([path.join(".")])),
214
+ _.set(getIndexedPath('uploadStatus'), 'loading')
215
+ ))
216
+ callIfFunction(onChangeFile,file)
217
+
218
+ loading.open()
219
+ uploadFetcher(file)
220
+ .then(({file, uploadStatus, response}) => {
221
+ loading.close()
222
+ const list = (form.getValue(getPath()) || [])
223
+ const index = list.findIndex((f) => f.uid === uid)
224
+ if (index < 0) {
225
+ form.setMeta(_.update(['submittingFiles'], (v) => v - 1))
226
+ return
227
+ }
228
+ const getIndexedPath = createGetIndexedPath(index)
229
+ form.clearErrors()
230
+ form.setValue(getIndexedPath('file'), response, false)
231
+ form.setMeta(_.flow(
232
+ _.update('uploadingPaths', _.difference(_,[path.join(".")])),
233
+ _.update(['submittingFiles'], (v) => v - 1),
234
+ _.update(['submittedFiles'], (v) => (v || []).concat([{path, file}])),
235
+ _.set(getIndexedPath('uploadStatus'), uploadStatus)
236
+ ))
237
+ callIfFunction(onSuccess, {file, uploadStatus})
238
+ }).catch((e) => {
239
+ loading.close()
240
+ const list = (form.getValue(getPath()) || [])
241
+ const index = list.findIndex((f) => f.uid === uid)
242
+ if (index < 0) {
243
+ form.setMeta(_.update(['submittingFiles'], (v) => v - 1))
244
+ return
245
+ }
246
+ const getIndexedPath = createGetIndexedPath(index)
247
+ form.setError(getIndexedPath('file').join('.'), callIfFunction(ajaxError,_.get('[1].status',e)))
248
+ if (oldFile) {
249
+ form.setValues(
250
+ _.flow(
251
+ _.set(getIndexedPath('filename'), oldFilename),
252
+ _.set(getIndexedPath('file'), oldFile),
253
+ ),
254
+ false
255
+ )
256
+ } else {
257
+ form.setValues(
258
+ _.update(getPath(), _.filter((f) => f.uid !== uid)),
259
+ false
260
+ )
261
+ }
262
+ form.setMeta(_.flow(
263
+ _.update('uploadingPaths', _.difference(_,[path.join(".")])),
264
+ _.update(['submittingFiles'], (v) => v - 1),
265
+ _.update(['submittedFiles'], (v) => (v || []).concat([{path, file}])),
266
+ _.set(getIndexedPath('uploadStatus'), oldUploadStatus)
267
+ ))
268
+ callIfFunction(onFailure)
269
+ })
270
+ if (eventTarget && eventTarget.parentNode && typeof eventTarget.parentNode.click === 'function')
271
+ eventTarget.parentNode.click()
272
+ }
273
+
274
+ const listenToClose = () => {
275
+ }
276
+
277
+ const handleClick = (e) => {
278
+ callIfFunction(onClick,e)
279
+ listenToClose()
280
+ }
281
+ const handleTouchEnd = (e) => {
282
+ callIfFunction(onTouchEnd,e)
283
+ listenToClose()
284
+ }
285
+
286
+ return children(
287
+ <FileInput multiple={multiple} onChange={handleFileEvent} onClick={handleClick} tabIndex={-1} onTouchEnd={handleTouchEnd}/>,
288
+ {
289
+ isLoading: loading.isOpen,
290
+ handleFile,
291
+ handleFileEvent,
292
+ Input: FileInput
293
+ }
294
+ )
295
+ }
296
+
297
+
package/.babelrc DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "presets": [
3
- "@babel/preset-react",
4
- "@babel/preset-flow",
5
- [
6
- "@babel/preset-env",
7
- {
8
- "modules": false
9
- }
10
- ]
11
- ],
12
- "plugins": [
13
- "lodash",
14
- "macros",
15
- "@babel/plugin-proposal-export-namespace-from",
16
- "@babel/plugin-proposal-throw-expressions",
17
- "@babel/plugin-syntax-import-meta",
18
- "@babel/plugin-proposal-json-strings",
19
- "@babel/plugin-syntax-dynamic-import",
20
- "@babel/plugin-transform-arrow-functions",
21
- "@babel/plugin-transform-spread",
22
- "@babel/plugin-proposal-optional-chaining",
23
- "@babel/plugin-proposal-object-rest-spread",
24
- ["@babel/plugin-proposal-class-properties", {"loose": true}],
25
- ["@babel/plugin-transform-private-methods", {"loose": true}],
26
- ["@babel/plugin-transform-private-property-in-object", {"loose": true}]
27
- ]
28
- }