@toptal/picasso-forms 6.0.5 → 7.1.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.
- package/{dist-package/Autocomplete → Autocomplete}/Autocomplete.d.ts +0 -0
- package/{dist-package/Autocomplete → Autocomplete}/Autocomplete.js +0 -0
- package/{dist-package/Autocomplete → Autocomplete}/Autocomplete.js.map +0 -0
- package/{dist-package/Autocomplete → Autocomplete}/index.d.ts +0 -0
- package/{dist-package/Autocomplete → Autocomplete}/index.js +0 -0
- package/{dist-package/Autocomplete → Autocomplete}/index.js.map +0 -0
- package/{dist-package/ButtonCheckbox → ButtonCheckbox}/ButtonCheckbox.d.ts +0 -0
- package/{dist-package/ButtonCheckbox → ButtonCheckbox}/ButtonCheckbox.js +0 -0
- package/{dist-package/ButtonCheckbox → ButtonCheckbox}/ButtonCheckbox.js.map +0 -0
- package/{dist-package/ButtonCheckbox → ButtonCheckbox}/index.d.ts +0 -0
- package/{dist-package/ButtonCheckbox → ButtonCheckbox}/index.js +0 -0
- package/{dist-package/ButtonCheckbox → ButtonCheckbox}/index.js.map +0 -0
- package/{dist-package/ButtonRadio → ButtonRadio}/ButtonRadio.d.ts +0 -0
- package/{dist-package/ButtonRadio → ButtonRadio}/ButtonRadio.js +0 -0
- package/{dist-package/ButtonRadio → ButtonRadio}/ButtonRadio.js.map +0 -0
- package/{dist-package/ButtonRadio → ButtonRadio}/index.d.ts +0 -0
- package/{dist-package/ButtonRadio → ButtonRadio}/index.js +0 -0
- package/{dist-package/ButtonRadio → ButtonRadio}/index.js.map +0 -0
- package/{dist-package/Checkbox → Checkbox}/Checkbox.d.ts +0 -0
- package/{dist-package/Checkbox → Checkbox}/Checkbox.js +0 -0
- package/{dist-package/Checkbox → Checkbox}/Checkbox.js.map +0 -0
- package/{dist-package/Checkbox → Checkbox}/index.d.ts +0 -0
- package/{dist-package/Checkbox → Checkbox}/index.js +0 -0
- package/{dist-package/Checkbox → Checkbox}/index.js.map +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/CheckboxGroup.d.ts +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/CheckboxGroup.js +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/CheckboxGroup.js.map +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/CheckboxGroupContext.d.ts +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/CheckboxGroupContext.js +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/CheckboxGroupContext.js.map +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/index.d.ts +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/index.js +0 -0
- package/{dist-package/CheckboxGroup → CheckboxGroup}/index.js.map +0 -0
- package/{dist-package/DatePicker → DatePicker}/DatePicker.d.ts +0 -0
- package/{dist-package/DatePicker → DatePicker}/DatePicker.js +0 -0
- package/{dist-package/DatePicker → DatePicker}/DatePicker.js.map +0 -0
- package/{dist-package/DatePicker → DatePicker}/index.d.ts +0 -0
- package/{dist-package/DatePicker → DatePicker}/index.js +0 -0
- package/{dist-package/DatePicker → DatePicker}/index.js.map +0 -0
- package/{dist-package/FieldWrapper → FieldWrapper}/FieldWrapper.d.ts +0 -0
- package/{dist-package/FieldWrapper → FieldWrapper}/FieldWrapper.js +0 -0
- package/{dist-package/FieldWrapper → FieldWrapper}/FieldWrapper.js.map +0 -0
- package/{dist-package/FieldWrapper → FieldWrapper}/index.d.ts +0 -0
- package/{dist-package/FieldWrapper → FieldWrapper}/index.js +0 -0
- package/{dist-package/FieldWrapper → FieldWrapper}/index.js.map +0 -0
- package/{dist-package/FileInput → FileInput}/FileInput.d.ts +0 -0
- package/{dist-package/FileInput → FileInput}/FileInput.js +0 -0
- package/{dist-package/FileInput → FileInput}/FileInput.js.map +0 -0
- package/{dist-package/FileInput → FileInput}/index.d.ts +0 -0
- package/{dist-package/FileInput → FileInput}/index.js +0 -0
- package/{dist-package/FileInput → FileInput}/index.js.map +0 -0
- package/{dist-package/Form → Form}/Form.d.ts +0 -0
- package/{dist-package/Form → Form}/Form.js +0 -0
- package/{dist-package/Form → Form}/Form.js.map +0 -0
- package/{dist-package/Form → Form}/FormContext.d.ts +0 -0
- package/{dist-package/Form → Form}/FormContext.js +0 -0
- package/{dist-package/Form → Form}/FormContext.js.map +0 -0
- package/{dist-package/Form → Form}/index.d.ts +0 -0
- package/{dist-package/Form → Form}/index.js +0 -0
- package/{dist-package/Form → Form}/index.js.map +0 -0
- package/{dist-package/FormConfig → FormConfig}/FormConfig.d.ts +0 -0
- package/{dist-package/FormConfig → FormConfig}/FormConfig.js +0 -0
- package/{dist-package/FormConfig → FormConfig}/FormConfig.js.map +0 -0
- package/{dist-package/FormConfig → FormConfig}/index.d.ts +0 -0
- package/{dist-package/FormConfig → FormConfig}/index.js +0 -0
- package/{dist-package/FormConfig → FormConfig}/index.js.map +0 -0
- package/{dist-package/Input → Input}/Input.d.ts +0 -0
- package/Input/Input.js +25 -0
- package/Input/Input.js.map +1 -0
- package/{dist-package/Input → Input}/index.d.ts +0 -0
- package/{dist-package/Input → Input}/index.js +0 -0
- package/{dist-package/Input → Input}/index.js.map +0 -0
- package/{dist-package/NumberInput → NumberInput}/NumberInput.d.ts +0 -0
- package/{dist-package/NumberInput → NumberInput}/NumberInput.js +0 -0
- package/{dist-package/NumberInput → NumberInput}/NumberInput.js.map +0 -0
- package/{dist-package/NumberInput → NumberInput}/index.d.ts +0 -0
- package/{dist-package/NumberInput → NumberInput}/index.js +0 -0
- package/{dist-package/NumberInput → NumberInput}/index.js.map +0 -0
- package/{dist-package/Radio → Radio}/Radio.d.ts +0 -0
- package/{dist-package/Radio → Radio}/Radio.js +0 -0
- package/{dist-package/Radio → Radio}/Radio.js.map +0 -0
- package/{dist-package/Radio → Radio}/index.d.ts +0 -0
- package/{dist-package/Radio → Radio}/index.js +0 -0
- package/{dist-package/Radio → Radio}/index.js.map +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/RadioGroup.d.ts +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/RadioGroup.js +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/RadioGroup.js.map +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/RadioGroupContext.d.ts +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/RadioGroupContext.js +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/RadioGroupContext.js.map +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/index.d.ts +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/index.js +0 -0
- package/{dist-package/RadioGroup → RadioGroup}/index.js.map +0 -0
- package/{dist-package/Rating → Rating}/Rating.d.ts +0 -0
- package/{dist-package/Rating → Rating}/Rating.js +0 -0
- package/{dist-package/Rating → Rating}/Rating.js.map +0 -0
- package/{dist-package/Rating → Rating}/index.d.ts +0 -0
- package/{dist-package/Rating → Rating}/index.js +0 -0
- package/{dist-package/Rating → Rating}/index.js.map +0 -0
- package/{dist-package/Select → Select}/Select.d.ts +0 -0
- package/{dist-package/Select → Select}/Select.js +0 -0
- package/{dist-package/Select → Select}/Select.js.map +0 -0
- package/{dist-package/Select → Select}/index.d.ts +0 -0
- package/{dist-package/Select → Select}/index.js +0 -0
- package/{dist-package/Select → Select}/index.js.map +0 -0
- package/{dist-package/SubmitButton → SubmitButton}/SubmitButton.d.ts +0 -0
- package/{dist-package/SubmitButton → SubmitButton}/SubmitButton.js +0 -0
- package/{dist-package/SubmitButton → SubmitButton}/SubmitButton.js.map +0 -0
- package/{dist-package/SubmitButton → SubmitButton}/index.d.ts +0 -0
- package/{dist-package/SubmitButton → SubmitButton}/index.js +0 -0
- package/{dist-package/SubmitButton → SubmitButton}/index.js.map +0 -0
- package/{dist-package/Switch → Switch}/Switch.d.ts +0 -0
- package/{dist-package/Switch → Switch}/Switch.js +0 -0
- package/{dist-package/Switch → Switch}/Switch.js.map +0 -0
- package/{dist-package/Switch → Switch}/index.d.ts +0 -0
- package/{dist-package/Switch → Switch}/index.js +0 -0
- package/{dist-package/Switch → Switch}/index.js.map +0 -0
- package/{dist-package/TagSelector → TagSelector}/TagSelector.d.ts +0 -0
- package/{dist-package/TagSelector → TagSelector}/TagSelector.js +0 -0
- package/{dist-package/TagSelector → TagSelector}/TagSelector.js.map +0 -0
- package/{dist-package/TagSelector → TagSelector}/index.d.ts +0 -0
- package/{dist-package/TagSelector → TagSelector}/index.js +0 -0
- package/{dist-package/TagSelector → TagSelector}/index.js.map +0 -0
- package/{dist-package/TimePicker → TimePicker}/TimePicker.d.ts +0 -0
- package/{dist-package/TimePicker → TimePicker}/TimePicker.js +0 -0
- package/{dist-package/TimePicker → TimePicker}/TimePicker.js.map +0 -0
- package/{dist-package/TimePicker → TimePicker}/index.d.ts +0 -0
- package/{dist-package/TimePicker → TimePicker}/index.js +0 -0
- package/{dist-package/TimePicker → TimePicker}/index.js.map +0 -0
- package/{dist-package/index.d.ts → index.d.ts} +0 -0
- package/{dist-package/index.js → index.js} +0 -0
- package/{dist-package/index.js.map → index.js.map} +0 -0
- package/package.json +6 -6
- package/{dist-package/utils → utils}/flat-map.d.ts +0 -0
- package/{dist-package/utils → utils}/flat-map.js +0 -0
- package/{dist-package/utils → utils}/flat-map.js.map +0 -0
- package/{dist-package/utils → utils}/index.d.ts +0 -0
- package/{dist-package/utils → utils}/index.js +0 -0
- package/{dist-package/utils → utils}/index.js.map +0 -0
- package/{dist-package/utils → utils}/scroll-to-error-decorator.d.ts +0 -0
- package/{dist-package/utils → utils}/scroll-to-error-decorator.js +0 -0
- package/{dist-package/utils → utils}/scroll-to-error-decorator.js.map +0 -0
- package/{dist-package/utils → utils}/validators.d.ts +0 -0
- package/{dist-package/utils → utils}/validators.js +0 -0
- package/{dist-package/utils → utils}/validators.js.map +0 -0
- package/CHANGELOG.md +0 -657
- package/dist-package/Input/Input.js +0 -26
- package/dist-package/Input/Input.js.map +0 -1
- package/dist-package/Input/utils/get-input-name.d.ts +0 -2
- package/dist-package/Input/utils/get-input-name.js +0 -9
- package/dist-package/Input/utils/get-input-name.js.map +0 -1
- package/dist-package/Input/utils/get-input-name.test.d.ts +0 -1
- package/dist-package/Input/utils/get-input-name.test.js +0 -12
- package/dist-package/Input/utils/get-input-name.test.js.map +0 -1
- package/dist-package/README.md +0 -29
- package/dist-package/package.json +0 -44
- package/src/Autocomplete/Autocomplete.tsx +0 -21
- package/src/Autocomplete/index.ts +0 -1
- package/src/ButtonCheckbox/ButtonCheckbox.tsx +0 -57
- package/src/ButtonCheckbox/index.ts +0 -1
- package/src/ButtonRadio/ButtonRadio.tsx +0 -24
- package/src/ButtonRadio/index.ts +0 -1
- package/src/Checkbox/Checkbox.tsx +0 -73
- package/src/Checkbox/__snapshots__/test.tsx.snap +0 -254
- package/src/Checkbox/index.ts +0 -1
- package/src/Checkbox/test.tsx +0 -91
- package/src/CheckboxGroup/CheckboxGroup.tsx +0 -30
- package/src/CheckboxGroup/CheckboxGroupContext.ts +0 -3
- package/src/CheckboxGroup/index.ts +0 -3
- package/src/CheckboxGroup/test.tsx +0 -35
- package/src/DatePicker/DatePicker.tsx +0 -26
- package/src/DatePicker/index.ts +0 -1
- package/src/FieldWrapper/FieldWrapper.tsx +0 -287
- package/src/FieldWrapper/index.ts +0 -2
- package/src/FieldWrapper/story/index.jsx +0 -137
- package/src/FileInput/FileInput.tsx +0 -66
- package/src/FileInput/index.ts +0 -1
- package/src/Form/Form.tsx +0 -181
- package/src/Form/FormContext.ts +0 -38
- package/src/Form/__image_snapshots__/form-default-snap.png +0 -0
- package/src/Form/__image_snapshots__/form-form-level-configurations-snap.png +0 -0
- package/src/Form/__snapshots__/test.tsx.snap +0 -61
- package/src/Form/index.ts +0 -1
- package/src/Form/story/BackendCommunication.example.tsx +0 -139
- package/src/Form/story/CustomFormLevelConfiguration.example.tsx +0 -26
- package/src/Form/story/CustomValidator.example.tsx +0 -45
- package/src/Form/story/Default.example.tsx +0 -177
- package/src/Form/story/FileInput.example.tsx +0 -42
- package/src/Form/story/ParseInput.example.tsx +0 -28
- package/src/Form/story/TitleCase.example.tsx +0 -167
- package/src/Form/story/ValidateOnSubmit.example.tsx +0 -85
- package/src/Form/story/index.jsx +0 -203
- package/src/Form/test.tsx +0 -27
- package/src/FormConfig/FormConfig.ts +0 -12
- package/src/FormConfig/index.ts +0 -1
- package/src/FormConfig/test.tsx +0 -44
- package/src/Input/Input.tsx +0 -27
- package/src/Input/index.ts +0 -1
- package/src/Input/test.tsx +0 -34
- package/src/Input/utils/get-input-name.test.ts +0 -16
- package/src/Input/utils/get-input-name.ts +0 -11
- package/src/NumberInput/NumberInput.tsx +0 -45
- package/src/NumberInput/index.ts +0 -1
- package/src/Radio/Radio.tsx +0 -24
- package/src/Radio/__snapshots__/test.tsx.snap +0 -231
- package/src/Radio/index.ts +0 -1
- package/src/Radio/test.tsx +0 -49
- package/src/RadioGroup/RadioGroup.tsx +0 -39
- package/src/RadioGroup/RadioGroupContext.ts +0 -3
- package/src/RadioGroup/index.ts +0 -3
- package/src/RadioGroup/test.tsx +0 -35
- package/src/Rating/Rating.tsx +0 -22
- package/src/Rating/index.ts +0 -1
- package/src/Select/Select.tsx +0 -47
- package/src/Select/index.ts +0 -1
- package/src/SubmitButton/SubmitButton.tsx +0 -70
- package/src/SubmitButton/__image_snapshots__/submitbutton-button-types-snap.png +0 -0
- package/src/SubmitButton/__image_snapshots__/submitbutton-default-snap.png +0 -0
- package/src/SubmitButton/index.ts +0 -6
- package/src/SubmitButton/story/ButtonTypes.example.tsx +0 -46
- package/src/SubmitButton/story/Default.example.tsx +0 -15
- package/src/SubmitButton/story/index.jsx +0 -32
- package/src/Switch/Switch.tsx +0 -23
- package/src/Switch/index.ts +0 -1
- package/src/TagSelector/TagSelector.tsx +0 -25
- package/src/TagSelector/index.ts +0 -1
- package/src/TimePicker/TimePicker.tsx +0 -24
- package/src/TimePicker/index.ts +0 -1
- package/src/index.ts +0 -16
- package/src/story/Deserialization.example.tsx +0 -34
- package/src/story/FormSpy.example.tsx +0 -42
- package/src/story/index.jsx +0 -37
- package/src/utils/flat-map.ts +0 -4
- package/src/utils/index.ts +0 -3
- package/src/utils/scroll-to-error-decorator.ts +0 -78
- package/src/utils/validators.ts +0 -18
- package/tsconfig.build.json +0 -7
package/src/Form/Form.tsx
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, ReactNode, useRef } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
Form as FinalForm,
|
|
4
|
-
FormProps as FinalFormProps
|
|
5
|
-
} from 'react-final-form'
|
|
6
|
-
import { FormApi, SubmissionErrors, getIn, setIn, AnyObject } from 'final-form'
|
|
7
|
-
import { Form as PicassoForm, Container } from '@toptal/picasso'
|
|
8
|
-
import { useNotifications } from '@toptal/picasso/utils'
|
|
9
|
-
|
|
10
|
-
import Autocomplete from '../Autocomplete'
|
|
11
|
-
import Input from '../Input'
|
|
12
|
-
import Select from '../Select'
|
|
13
|
-
import Radio from '../Radio'
|
|
14
|
-
import ButtonRadio from '../ButtonRadio'
|
|
15
|
-
import RadioGroup from '../RadioGroup'
|
|
16
|
-
import Checkbox from '../Checkbox'
|
|
17
|
-
import ButtonCheckbox from '../ButtonCheckbox'
|
|
18
|
-
import CheckboxGroup from '../CheckboxGroup'
|
|
19
|
-
import NumberInput from '../NumberInput'
|
|
20
|
-
import FileInput from '../FileInput'
|
|
21
|
-
import DatePicker from '../DatePicker'
|
|
22
|
-
import TimePicker from '../TimePicker'
|
|
23
|
-
import TagSelector from '../TagSelector'
|
|
24
|
-
import SubmitButton from '../SubmitButton'
|
|
25
|
-
import Switch from '../Switch'
|
|
26
|
-
import Rating from '../Rating'
|
|
27
|
-
import { FormConfigContext } from '../FormConfig'
|
|
28
|
-
import { createScrollToErrorDecorator } from '../utils'
|
|
29
|
-
import {
|
|
30
|
-
FormContext,
|
|
31
|
-
Validators,
|
|
32
|
-
FormContextProps,
|
|
33
|
-
createFormContext
|
|
34
|
-
} from './FormContext'
|
|
35
|
-
|
|
36
|
-
export type Props<T = AnyObject> = FinalFormProps<T> & {
|
|
37
|
-
autoComplete?: HTMLFormElement['autocomplete']
|
|
38
|
-
successSubmitMessage?: ReactNode
|
|
39
|
-
failedSubmitMessage?: ReactNode
|
|
40
|
-
scrollOffsetTop?: number
|
|
41
|
-
'data-testid'?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const getValidationErrors = (
|
|
45
|
-
validators: Validators,
|
|
46
|
-
formValues: any,
|
|
47
|
-
form: FormApi<any>
|
|
48
|
-
): SubmissionErrors | void => {
|
|
49
|
-
let errors: SubmissionErrors
|
|
50
|
-
|
|
51
|
-
Object.entries(validators).forEach(([key, validator]) => {
|
|
52
|
-
const fieldValue = getIn(formValues, key)
|
|
53
|
-
const fieldMetaState = form.getFieldState(key)
|
|
54
|
-
|
|
55
|
-
if (!validator) {
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const error = validator(fieldValue, formValues, fieldMetaState)
|
|
60
|
-
|
|
61
|
-
if (error) {
|
|
62
|
-
errors = setIn(errors || {}, key, error)
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
return errors
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const Form = <T extends any = AnyObject>(props: Props<T>) => {
|
|
70
|
-
const {
|
|
71
|
-
children,
|
|
72
|
-
autoComplete,
|
|
73
|
-
onSubmit,
|
|
74
|
-
successSubmitMessage,
|
|
75
|
-
failedSubmitMessage,
|
|
76
|
-
decorators = [],
|
|
77
|
-
'data-testid': dataTestId,
|
|
78
|
-
...rest
|
|
79
|
-
} = props
|
|
80
|
-
const { showSuccess, showError } = useNotifications()
|
|
81
|
-
const scrollToErrorDecorator = useMemo(
|
|
82
|
-
() => createScrollToErrorDecorator(),
|
|
83
|
-
[]
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
const validationObject = useRef<FormContextProps>(createFormContext())
|
|
87
|
-
|
|
88
|
-
const showSuccessNotification = () => {
|
|
89
|
-
if (!successSubmitMessage) {
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
showSuccess(successSubmitMessage)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const showErrorNotification = (errors: SubmissionErrors) => {
|
|
97
|
-
if (typeof errors === 'string') {
|
|
98
|
-
showError(errors, undefined, { persist: true })
|
|
99
|
-
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (!failedSubmitMessage) {
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
showError(failedSubmitMessage, undefined, { persist: true })
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const handleSubmit = async (
|
|
111
|
-
values: T,
|
|
112
|
-
form: FormApi<T>,
|
|
113
|
-
callback?: (errors?: SubmissionErrors) => void
|
|
114
|
-
) => {
|
|
115
|
-
const validationErrors = getValidationErrors(
|
|
116
|
-
validationObject.current.getValidators(),
|
|
117
|
-
values,
|
|
118
|
-
form
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
if (validationErrors) {
|
|
122
|
-
return validationErrors
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const submissionErrors = await onSubmit(values, form, callback)
|
|
126
|
-
|
|
127
|
-
if (!submissionErrors) {
|
|
128
|
-
showSuccessNotification()
|
|
129
|
-
} else {
|
|
130
|
-
showErrorNotification(submissionErrors)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return submissionErrors
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return (
|
|
137
|
-
<FormContext.Provider value={validationObject}>
|
|
138
|
-
<FinalForm
|
|
139
|
-
render={({ handleSubmit }) => (
|
|
140
|
-
<Container>
|
|
141
|
-
<PicassoForm
|
|
142
|
-
autoComplete={autoComplete}
|
|
143
|
-
onSubmit={handleSubmit}
|
|
144
|
-
data-testid={dataTestId}
|
|
145
|
-
>
|
|
146
|
-
{children}
|
|
147
|
-
</PicassoForm>
|
|
148
|
-
</Container>
|
|
149
|
-
)}
|
|
150
|
-
onSubmit={handleSubmit}
|
|
151
|
-
decorators={[...decorators, scrollToErrorDecorator]}
|
|
152
|
-
{...rest}
|
|
153
|
-
/>
|
|
154
|
-
</FormContext.Provider>
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
Form.defaultProps = {}
|
|
159
|
-
|
|
160
|
-
Form.displayName = 'Form'
|
|
161
|
-
|
|
162
|
-
Form.Autocomplete = Autocomplete
|
|
163
|
-
Form.Input = Input
|
|
164
|
-
Form.Select = Select
|
|
165
|
-
Form.Radio = Radio
|
|
166
|
-
Form.ButtonRadio = ButtonRadio
|
|
167
|
-
Form.RadioGroup = RadioGroup
|
|
168
|
-
Form.Checkbox = Checkbox
|
|
169
|
-
Form.ButtonCheckbox = ButtonCheckbox
|
|
170
|
-
Form.CheckboxGroup = CheckboxGroup
|
|
171
|
-
Form.NumberInput = NumberInput
|
|
172
|
-
Form.FileInput = FileInput
|
|
173
|
-
Form.DatePicker = DatePicker
|
|
174
|
-
Form.TimePicker = TimePicker
|
|
175
|
-
Form.TagSelector = TagSelector
|
|
176
|
-
Form.SubmitButton = SubmitButton
|
|
177
|
-
Form.ConfigProvider = FormConfigContext.Provider
|
|
178
|
-
Form.Switch = Switch
|
|
179
|
-
Form.Rating = Rating
|
|
180
|
-
|
|
181
|
-
export default Form
|
package/src/Form/FormContext.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, MutableRefObject } from 'react'
|
|
2
|
-
import { FieldValidator } from 'final-form'
|
|
3
|
-
|
|
4
|
-
export type Validators = Record<string, FieldValidator<unknown>>
|
|
5
|
-
|
|
6
|
-
export type FormContextProps = {
|
|
7
|
-
getValidators: () => Validators
|
|
8
|
-
setValidators: (fieldName: string, validator: FieldValidator<unknown>) => void
|
|
9
|
-
clearValidators: (fieldName: string) => void
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const createFormContext = (): FormContextProps => {
|
|
13
|
-
const validators: Validators = {}
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
getValidators: () => validators,
|
|
17
|
-
setValidators: (fieldName, validator) => {
|
|
18
|
-
validators[fieldName] = validator
|
|
19
|
-
},
|
|
20
|
-
clearValidators: fieldName => {
|
|
21
|
-
delete validators[fieldName]
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const FormContext = createContext<MutableRefObject<
|
|
27
|
-
FormContextProps
|
|
28
|
-
> | null>(null)
|
|
29
|
-
|
|
30
|
-
export const useFormContext = () => {
|
|
31
|
-
const context = useContext(FormContext)
|
|
32
|
-
|
|
33
|
-
if (!context) {
|
|
34
|
-
throw new Error('Form Field cannot be rendered outside Form component')
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return context.current
|
|
38
|
-
}
|
|
Binary file
|
|
Binary file
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`Form renders 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<div
|
|
6
|
-
class="Picasso-root"
|
|
7
|
-
>
|
|
8
|
-
<div
|
|
9
|
-
class=""
|
|
10
|
-
>
|
|
11
|
-
<form>
|
|
12
|
-
<div
|
|
13
|
-
class="PicassoFormField-root"
|
|
14
|
-
data-field-has-error="false"
|
|
15
|
-
>
|
|
16
|
-
<div
|
|
17
|
-
class="MuiInputBase-root MuiOutlinedInput-root PicassoOutlinedInput-root PicassoInput-root PicassoOutlinedInput-rootAuto PicassoOutlinedInput-rootMedium MuiInputBase-adornedStart MuiOutlinedInput-adornedStart MuiInputBase-adornedEnd MuiOutlinedInput-adornedEnd"
|
|
18
|
-
>
|
|
19
|
-
<input
|
|
20
|
-
aria-invalid="false"
|
|
21
|
-
autocomplete="none"
|
|
22
|
-
class="MuiInputBase-input MuiOutlinedInput-input PicassoOutlinedInput-input PicassoOutlinedInput-inputMedium MuiInputBase-inputAdornedStart MuiOutlinedInput-inputAdornedStart MuiInputBase-inputAdornedEnd MuiOutlinedInput-inputAdornedEnd"
|
|
23
|
-
id="test"
|
|
24
|
-
name="test"
|
|
25
|
-
placeholder="test input"
|
|
26
|
-
type="text"
|
|
27
|
-
value=""
|
|
28
|
-
/>
|
|
29
|
-
<fieldset
|
|
30
|
-
aria-hidden="true"
|
|
31
|
-
class="PrivateNotchedOutline-root MuiOutlinedInput-notchedOutline PicassoOutlinedInput-notchedOutline"
|
|
32
|
-
style="padding-left: 8px;"
|
|
33
|
-
>
|
|
34
|
-
<legend
|
|
35
|
-
class="PrivateNotchedOutline-legend"
|
|
36
|
-
style="width: 0.01px;"
|
|
37
|
-
>
|
|
38
|
-
<span>
|
|
39
|
-
|
|
40
|
-
</span>
|
|
41
|
-
</legend>
|
|
42
|
-
</fieldset>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
<button
|
|
46
|
-
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primary PicassoButton-root"
|
|
47
|
-
data-component-type="button"
|
|
48
|
-
tabindex="0"
|
|
49
|
-
type="submit"
|
|
50
|
-
>
|
|
51
|
-
<span
|
|
52
|
-
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline PicassoButton-content"
|
|
53
|
-
>
|
|
54
|
-
Submit
|
|
55
|
-
</span>
|
|
56
|
-
</button>
|
|
57
|
-
</form>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
`;
|
package/src/Form/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Form'
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import React, { useCallback } from 'react'
|
|
2
|
-
import { Container } from '@toptal/picasso'
|
|
3
|
-
import { Form } from '@toptal/picasso-forms'
|
|
4
|
-
|
|
5
|
-
const BackendCommunicationExample = () => {
|
|
6
|
-
const handleSuccessSubmit = useCallback(
|
|
7
|
-
(values: any) => api.successSubmit(values),
|
|
8
|
-
[]
|
|
9
|
-
)
|
|
10
|
-
const handleSubmitWithInlineError = useCallback(
|
|
11
|
-
(values: any) => api.submitWithInlineError(values),
|
|
12
|
-
[]
|
|
13
|
-
)
|
|
14
|
-
const handleSubmitWithCustomNotificationError = useCallback(
|
|
15
|
-
(values: any) => api.submitWithCustomNotificationError(values),
|
|
16
|
-
[]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<Container
|
|
21
|
-
style={{
|
|
22
|
-
display: 'grid',
|
|
23
|
-
gap: '2rem',
|
|
24
|
-
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))'
|
|
25
|
-
}}
|
|
26
|
-
>
|
|
27
|
-
<Form
|
|
28
|
-
onSubmit={handleSuccessSubmit}
|
|
29
|
-
successSubmitMessage='Login successful!'
|
|
30
|
-
>
|
|
31
|
-
<Form.Input
|
|
32
|
-
required
|
|
33
|
-
name='successName'
|
|
34
|
-
label='First name'
|
|
35
|
-
placeholder='e.g. Bruce'
|
|
36
|
-
width='full'
|
|
37
|
-
/>
|
|
38
|
-
<Form.Input
|
|
39
|
-
required
|
|
40
|
-
name='successSurname'
|
|
41
|
-
label='Last name'
|
|
42
|
-
placeholder='e.g. Wayne'
|
|
43
|
-
width='full'
|
|
44
|
-
/>
|
|
45
|
-
|
|
46
|
-
<Container top='small'>
|
|
47
|
-
<Form.SubmitButton
|
|
48
|
-
variant='positive'
|
|
49
|
-
data-testid='success-submit-button'
|
|
50
|
-
>
|
|
51
|
-
Login Success
|
|
52
|
-
</Form.SubmitButton>
|
|
53
|
-
</Container>
|
|
54
|
-
</Form>
|
|
55
|
-
|
|
56
|
-
<Form
|
|
57
|
-
onSubmit={handleSubmitWithInlineError}
|
|
58
|
-
failedSubmitMessage='Login failed! Please try another combination of first and last names.'
|
|
59
|
-
>
|
|
60
|
-
<Form.Input
|
|
61
|
-
required
|
|
62
|
-
name='inlineErrorName'
|
|
63
|
-
label='First name'
|
|
64
|
-
placeholder='e.g. Bruce'
|
|
65
|
-
width='full'
|
|
66
|
-
/>
|
|
67
|
-
<Form.Input
|
|
68
|
-
required
|
|
69
|
-
name='inlineErrorSurname'
|
|
70
|
-
label='Last name'
|
|
71
|
-
placeholder='e.g. Wayne'
|
|
72
|
-
width='full'
|
|
73
|
-
/>
|
|
74
|
-
|
|
75
|
-
<Container top='small'>
|
|
76
|
-
<Form.SubmitButton
|
|
77
|
-
variant='negative'
|
|
78
|
-
data-testid='submit-with-inline-error-button'
|
|
79
|
-
>
|
|
80
|
-
Login with Inline Error
|
|
81
|
-
</Form.SubmitButton>
|
|
82
|
-
</Container>
|
|
83
|
-
</Form>
|
|
84
|
-
|
|
85
|
-
<Form onSubmit={handleSubmitWithCustomNotificationError}>
|
|
86
|
-
<Form.Input
|
|
87
|
-
required
|
|
88
|
-
name='customNotificationErrorName'
|
|
89
|
-
label='First name'
|
|
90
|
-
placeholder='e.g. Bruce'
|
|
91
|
-
width='full'
|
|
92
|
-
/>
|
|
93
|
-
<Form.Input
|
|
94
|
-
required
|
|
95
|
-
name='customNotificationErrorSurname'
|
|
96
|
-
label='Last name'
|
|
97
|
-
placeholder='e.g. Wayne'
|
|
98
|
-
width='full'
|
|
99
|
-
/>
|
|
100
|
-
|
|
101
|
-
<Container top='small'>
|
|
102
|
-
<Form.SubmitButton
|
|
103
|
-
variant='negative'
|
|
104
|
-
data-testid='submit-with-custom-notification-button'
|
|
105
|
-
>
|
|
106
|
-
Login with Custom Notification Error
|
|
107
|
-
</Form.SubmitButton>
|
|
108
|
-
</Container>
|
|
109
|
-
</Form>
|
|
110
|
-
</Container>
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// the emulation of the api call
|
|
115
|
-
const responseWithDelay = async (response: any) =>
|
|
116
|
-
new Promise(resolve => setTimeout(() => resolve(response), 2000))
|
|
117
|
-
|
|
118
|
-
const api = {
|
|
119
|
-
successSubmit: (values: any) => {
|
|
120
|
-
// do something with received values
|
|
121
|
-
console.log('Success submit. Form values:', values)
|
|
122
|
-
|
|
123
|
-
return responseWithDelay(undefined)
|
|
124
|
-
},
|
|
125
|
-
submitWithInlineError: (values: any) => {
|
|
126
|
-
console.log('Submit with Inline Errors. Form values:', values)
|
|
127
|
-
|
|
128
|
-
return responseWithDelay({
|
|
129
|
-
inlineErrorName: 'Unknown first name'
|
|
130
|
-
})
|
|
131
|
-
},
|
|
132
|
-
submitWithCustomNotificationError: (values: any) => {
|
|
133
|
-
console.log('Submit with Custom Notification Errors. Form values:', values)
|
|
134
|
-
|
|
135
|
-
return responseWithDelay('Custom Notification Message!')
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export default BackendCommunicationExample
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Container } from '@toptal/picasso'
|
|
3
|
-
import { Form, FormConfigProps } from '@toptal/picasso-forms'
|
|
4
|
-
|
|
5
|
-
const formConfig: FormConfigProps = {
|
|
6
|
-
requiredVariant: 'asterisk'
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const Example = () => (
|
|
10
|
-
<Form.ConfigProvider value={formConfig}>
|
|
11
|
-
<Form onSubmit={() => {}}>
|
|
12
|
-
<Form.Input
|
|
13
|
-
required
|
|
14
|
-
name='formConfig.firstName'
|
|
15
|
-
label='First name'
|
|
16
|
-
placeholder='e.g. Bruce'
|
|
17
|
-
/>
|
|
18
|
-
|
|
19
|
-
<Container top='small'>
|
|
20
|
-
<Form.SubmitButton>Submit</Form.SubmitButton>
|
|
21
|
-
</Container>
|
|
22
|
-
</Form>
|
|
23
|
-
</Form.ConfigProvider>
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
export default Example
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Container } from '@toptal/picasso'
|
|
3
|
-
import { Form } from '@toptal/picasso-forms'
|
|
4
|
-
|
|
5
|
-
const minMaxValidator = (value?: string | number) => {
|
|
6
|
-
if (value === undefined) {
|
|
7
|
-
return undefined
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const number = Number(value)
|
|
11
|
-
|
|
12
|
-
if (number < 0) {
|
|
13
|
-
return "Age can't be negative"
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (number > 120) {
|
|
17
|
-
return "Age can't have value more than 120 years"
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return undefined
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const CustomValidatorExample = () => (
|
|
24
|
-
<Form onSubmit={values => window.alert(values)}>
|
|
25
|
-
<Form.Input
|
|
26
|
-
required
|
|
27
|
-
name='userName'
|
|
28
|
-
label='First name'
|
|
29
|
-
placeholder='e.g. Bruce'
|
|
30
|
-
/>
|
|
31
|
-
<Form.NumberInput
|
|
32
|
-
required
|
|
33
|
-
validate={minMaxValidator}
|
|
34
|
-
name='userAge'
|
|
35
|
-
label="What's your age?"
|
|
36
|
-
placeholder='e.g. 25'
|
|
37
|
-
/>
|
|
38
|
-
|
|
39
|
-
<Container top='small'>
|
|
40
|
-
<Form.SubmitButton>Submit</Form.SubmitButton>
|
|
41
|
-
</Container>
|
|
42
|
-
</Form>
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
export default CustomValidatorExample
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import { Container } from '@toptal/picasso'
|
|
3
|
-
import { Item } from '@toptal/picasso/Autocomplete'
|
|
4
|
-
import { isSubstring } from '@toptal/picasso/utils'
|
|
5
|
-
import { Form } from '@toptal/picasso-forms'
|
|
6
|
-
|
|
7
|
-
const countries = [
|
|
8
|
-
{ value: 'Afghanistan', text: 'Afghanistan' },
|
|
9
|
-
{ value: 'Albania', text: 'Albania' },
|
|
10
|
-
{ value: 'Algeria', text: 'Algeria' },
|
|
11
|
-
{ value: 'Belarus', text: 'Belarus' },
|
|
12
|
-
{ value: 'Croatia', text: 'Croatia' },
|
|
13
|
-
{ value: 'Lithuania', text: 'Lithuania' },
|
|
14
|
-
{ value: 'Slovakia', text: 'Slovakia' },
|
|
15
|
-
{ value: 'Spain', text: 'Spain' },
|
|
16
|
-
{ value: 'Ukraine', text: 'Ukraine' }
|
|
17
|
-
]
|
|
18
|
-
|
|
19
|
-
const skills = [
|
|
20
|
-
{ value: 0, text: 'HTML' },
|
|
21
|
-
{ value: 1, text: 'CSS' },
|
|
22
|
-
{ value: 2, text: 'Javascript' }
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
const EMPTY_INPUT_VALUE = ''
|
|
26
|
-
const getAutocompleteDisplayValue = (item: Item | null) =>
|
|
27
|
-
item?.text || EMPTY_INPUT_VALUE
|
|
28
|
-
|
|
29
|
-
const filterOptions = (str = '', options: Item[] = []): Item[] | null => {
|
|
30
|
-
if (!str) {
|
|
31
|
-
return options
|
|
32
|
-
}
|
|
33
|
-
const result = options.filter(option =>
|
|
34
|
-
option?.text ? isSubstring(str, option.text) : false
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
return result.length > 0 ? result : null
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const Example = () => {
|
|
41
|
-
const [skillInputValue, setSkillInputValue] = useState<string>(
|
|
42
|
-
EMPTY_INPUT_VALUE
|
|
43
|
-
)
|
|
44
|
-
const skillOptions = filterOptions(skillInputValue, skills)
|
|
45
|
-
|
|
46
|
-
const [autocompleteValue, setAutocompleteValue] = useState<string>(
|
|
47
|
-
EMPTY_INPUT_VALUE
|
|
48
|
-
)
|
|
49
|
-
const [autocompleteOptions, setAutocompleteOptions] = useState<Item[] | null>(
|
|
50
|
-
countries
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<Form
|
|
55
|
-
autoComplete='off'
|
|
56
|
-
onSubmit={values => window.alert(values)}
|
|
57
|
-
initialValues={{ gender: 'female' }}
|
|
58
|
-
>
|
|
59
|
-
<Form.Input
|
|
60
|
-
enableReset
|
|
61
|
-
onResetClick={(set: (value: string) => void) => {
|
|
62
|
-
set('')
|
|
63
|
-
}}
|
|
64
|
-
required
|
|
65
|
-
name='firstName'
|
|
66
|
-
label='First name'
|
|
67
|
-
placeholder='e.g. Bruce'
|
|
68
|
-
/>
|
|
69
|
-
<Form.Input
|
|
70
|
-
required
|
|
71
|
-
name='lastName'
|
|
72
|
-
label='Last name'
|
|
73
|
-
placeholder='e.g. Wayne'
|
|
74
|
-
/>
|
|
75
|
-
<Form.NumberInput
|
|
76
|
-
enableReset
|
|
77
|
-
required
|
|
78
|
-
name='age'
|
|
79
|
-
label="What's your age?"
|
|
80
|
-
placeholder='e.g. 25'
|
|
81
|
-
/>
|
|
82
|
-
<Form.RadioGroup name='gender' label='Gender'>
|
|
83
|
-
<Form.Radio label='Male' value='male' />
|
|
84
|
-
<Form.Radio label='Female' value='female' />
|
|
85
|
-
</Form.RadioGroup>
|
|
86
|
-
<Form.RadioGroup name='gender' label='Gender' horizontal spacing={8}>
|
|
87
|
-
<Form.ButtonRadio value='male'>Male</Form.ButtonRadio>
|
|
88
|
-
<Form.ButtonRadio value='female'>Female</Form.ButtonRadio>
|
|
89
|
-
</Form.RadioGroup>
|
|
90
|
-
<Form.DatePicker name='dateOfBirth' label='Date of birth' />
|
|
91
|
-
<Form.TimePicker name='timeOfBirth' label='Time of birth' />
|
|
92
|
-
<Form.TagSelector
|
|
93
|
-
name='skills'
|
|
94
|
-
label='Skills'
|
|
95
|
-
inputValue={skillInputValue}
|
|
96
|
-
options={skillOptions}
|
|
97
|
-
onInputChange={setSkillInputValue}
|
|
98
|
-
/>
|
|
99
|
-
<Form.CheckboxGroup name='hobbies' label='Hobbies'>
|
|
100
|
-
<Form.Checkbox label='Skiing' value='skiing' />
|
|
101
|
-
<Form.Checkbox label='Free diving' value='freeDiving' />
|
|
102
|
-
<Form.Checkbox label='Dancing' value='dancing' />
|
|
103
|
-
</Form.CheckboxGroup>
|
|
104
|
-
<Form.CheckboxGroup name='hobbies' label='Hobbies' horizontal spacing={8}>
|
|
105
|
-
<Form.ButtonCheckbox value='skiing'>Skiing</Form.ButtonCheckbox>
|
|
106
|
-
<Form.ButtonCheckbox value='freeDiving'>
|
|
107
|
-
Free diving
|
|
108
|
-
</Form.ButtonCheckbox>
|
|
109
|
-
<Form.ButtonCheckbox value='dancing'>Dancing</Form.ButtonCheckbox>
|
|
110
|
-
</Form.CheckboxGroup>
|
|
111
|
-
<Form.Select
|
|
112
|
-
enableReset
|
|
113
|
-
required
|
|
114
|
-
name='businessType'
|
|
115
|
-
label='Business type'
|
|
116
|
-
width='auto'
|
|
117
|
-
options={[
|
|
118
|
-
{ value: 0, text: 'Company' },
|
|
119
|
-
{ value: 1, text: 'Individual' }
|
|
120
|
-
]}
|
|
121
|
-
/>
|
|
122
|
-
<Form.Select
|
|
123
|
-
name='origin_country'
|
|
124
|
-
label='Origin country'
|
|
125
|
-
width='auto'
|
|
126
|
-
options={countries}
|
|
127
|
-
/>
|
|
128
|
-
<Form.Autocomplete
|
|
129
|
-
name='current_country'
|
|
130
|
-
label='Current country'
|
|
131
|
-
placeholder='Start typing country...'
|
|
132
|
-
width='auto'
|
|
133
|
-
value={autocompleteValue}
|
|
134
|
-
options={autocompleteOptions}
|
|
135
|
-
onSelect={(item: Item) => {
|
|
136
|
-
console.log('onSelect returns item object:', item)
|
|
137
|
-
|
|
138
|
-
const itemValue = getAutocompleteDisplayValue(item)
|
|
139
|
-
|
|
140
|
-
if (autocompleteValue !== itemValue) {
|
|
141
|
-
setAutocompleteValue(itemValue)
|
|
142
|
-
}
|
|
143
|
-
}}
|
|
144
|
-
onChange={(newValue: string) => {
|
|
145
|
-
console.log('onChange returns just item value:', newValue)
|
|
146
|
-
|
|
147
|
-
setAutocompleteOptions(filterOptions(newValue, countries))
|
|
148
|
-
setAutocompleteValue(newValue)
|
|
149
|
-
}}
|
|
150
|
-
getDisplayValue={getAutocompleteDisplayValue}
|
|
151
|
-
/>
|
|
152
|
-
<Form.Rating
|
|
153
|
-
name='rating'
|
|
154
|
-
label='How much do you love Picasso?'
|
|
155
|
-
required
|
|
156
|
-
/>
|
|
157
|
-
<Form.FileInput
|
|
158
|
-
required
|
|
159
|
-
name='avatar'
|
|
160
|
-
label='Avatar'
|
|
161
|
-
status='No file selected.'
|
|
162
|
-
/>
|
|
163
|
-
<Form.Checkbox
|
|
164
|
-
required
|
|
165
|
-
name='legal'
|
|
166
|
-
label='I confirm that I have legal permission from the client to feature this project.'
|
|
167
|
-
/>
|
|
168
|
-
<Form.Switch name='publicProfile' label='Public Profile' width='auto' />
|
|
169
|
-
|
|
170
|
-
<Container top='small'>
|
|
171
|
-
<Form.SubmitButton>Submit</Form.SubmitButton>
|
|
172
|
-
</Container>
|
|
173
|
-
</Form>
|
|
174
|
-
)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export default Example
|