-
Notifications
You must be signed in to change notification settings - Fork 4k
Expand file tree
/
Copy pathForm.js
More file actions
130 lines (108 loc) · 3.27 KB
/
Form.js
File metadata and controls
130 lines (108 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import cx from 'clsx'
import _ from 'lodash'
import PropTypes from 'prop-types'
import * as React from 'react'
import { getComponentType, getUnhandledProps, SUI, useKeyOnly, useWidthProp } from '../../lib'
import FormButton from './FormButton'
import FormCheckbox from './FormCheckbox'
import FormDropdown from './FormDropdown'
import FormField from './FormField'
import FormGroup from './FormGroup'
import FormInput from './FormInput'
import FormRadio from './FormRadio'
import FormSelect from './FormSelect'
import FormTextArea from './FormTextArea'
/**
* A Form displays a set of related user input fields in a structured way.
* @see Button
* @see Checkbox
* @see Dropdown
* @see Input
* @see Message
* @see Radio
* @see Select
*/
const Form = React.forwardRef(function (props, ref) {
const {
action,
children,
className,
error,
inverted,
loading,
reply,
size,
success,
unstackable,
warning,
widths,
} = props
const handleSubmit = (e, ...args) => {
// Heads up! Third party libs can pass own data as first argument, we need to check that it has preventDefault()
// method.
if (typeof action !== 'string') e.preventDefault?.()
props.onSubmit?.(e, props, ...args)
}
const classes = cx(
'ui',
size,
useKeyOnly(error, 'error'),
useKeyOnly(inverted, 'inverted'),
useKeyOnly(loading, 'loading'),
useKeyOnly(reply, 'reply'),
useKeyOnly(success, 'success'),
useKeyOnly(unstackable, 'unstackable'),
useKeyOnly(warning, 'warning'),
useWidthProp(widths, null, true),
'form',
className,
)
const rest = getUnhandledProps(Form, props)
const ElementType = getComponentType(props, { defaultAs: 'form' })
return (
<ElementType {...rest} action={action} className={classes} onSubmit={handleSubmit} ref={ref}>
{children}
</ElementType>
)
})
Form.displayName = 'Form'
Form.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
/** The HTML form action */
action: PropTypes.string,
/** Primary content. */
children: PropTypes.node,
/** Additional classes. */
className: PropTypes.string,
/** Automatically show any error Message children. */
error: PropTypes.bool,
/** A form can have its color inverted for contrast. */
inverted: PropTypes.bool,
/** Automatically show a loading indicator. */
loading: PropTypes.bool,
/** The HTML form submit handler. */
onSubmit: PropTypes.func,
/** A comment can contain a form to reply to a comment. This may have arbitrary content. */
reply: PropTypes.bool,
/** A form can vary in size. */
size: PropTypes.oneOf(_.without(SUI.SIZES, 'medium')),
/** Automatically show any success Message children. */
success: PropTypes.bool,
/** A form can prevent itself from stacking on mobile. */
unstackable: PropTypes.bool,
/** Automatically show any warning Message children. */
warning: PropTypes.bool,
/** Forms can automatically divide fields to be equal width. */
widths: PropTypes.oneOf(['equal']),
}
Form.Field = FormField
Form.Button = FormButton
Form.Checkbox = FormCheckbox
Form.Dropdown = FormDropdown
Form.Group = FormGroup
Form.Input = FormInput
Form.Radio = FormRadio
Form.Select = FormSelect
Form.TextArea = FormTextArea
export default Form