superglue 1.0.0 → 1.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.
- checksums.yaml +4 -4
- data/README.md +32 -0
- data/lib/generators/superglue/install/install_generator.rb +44 -0
- data/lib/generators/superglue/install/templates/erb/superglue.html.erb +5 -0
- data/lib/generators/superglue/install/templates/js/inputs.jsx +192 -124
- data/lib/generators/superglue/install/templates/ts/inputs.tsx +148 -141
- data/lib/generators/superglue/scaffold_controller/scaffold_controller_generator.rb +5 -1
- data/lib/generators/superglue/view_collection/view_collection_generator.rb +0 -8
- data/lib/superglue/rendering.rb +88 -0
- data/lib/superglue/resolver.rb +58 -0
- data/lib/superglue.rb +8 -0
- metadata +11 -8
- data/lib/generators/superglue/view_collection/templates/erb/edit.html.erb +0 -10
- data/lib/generators/superglue/view_collection/templates/erb/index.html.erb +0 -9
- data/lib/generators/superglue/view_collection/templates/erb/new.html.erb +0 -9
- data/lib/generators/superglue/view_collection/templates/erb/show.html.erb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4b39909974d5f15cf6353b2a5748e4e31878b3dee8622d8874cc18395bf684c
|
4
|
+
data.tar.gz: c375f0687470c2afb7de11fb1b566bd87e6a5e51d200faea291f42a7bb7b7b95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fa8626cc3b719c3df4f0c521e22a7bf7857bce6871c2b43bab714ab1ae019677bb8a854b257aa9a7181b928a399d518a6350f0b3aafcbe3237e3cd58ca4d8ea
|
7
|
+
data.tar.gz: 93798fbd725b53a4353415bc648fc7e8ffb0dffc046b10daa2a436398ea9c6d2e678a4ca0662d9e20ed001b1b5591830c81b982cfc7f6d9e6d69851e589c8ebb
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
<div align="center" style="padding: 30px 0px 20px 0px;">
|
2
|
+
<img src="https://thoughtbot.github.io/superglue/images/superglue.svg" data-origin="images/superglue.svg" alt="Logo" width=250>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
# Superglue Rails
|
6
|
+
Use classic Rails to build rich React Redux applications with **NO APIs** and
|
7
|
+
**NO client-side routing**.
|
8
|
+
|
9
|
+
This is the officially supported Rails adapter to [Superglue]. This gem will
|
10
|
+
add install and scaffold generators to your rails project.
|
11
|
+
|
12
|
+
To get started, visit the [documentation] and add this to your Gemfile
|
13
|
+
|
14
|
+
[documentation]: https://thoughtbot.github.io/superglue/
|
15
|
+
|
16
|
+
```
|
17
|
+
gem 'superglue'
|
18
|
+
```
|
19
|
+
|
20
|
+
Then run `bundle`
|
21
|
+
|
22
|
+
[](https://github.com/thoughtbot/superglue_rails/actions/workflows/build_rails.yml)
|
23
|
+
|
24
|
+
## Documentation
|
25
|
+
|
26
|
+
Documentation is hosted on [Github pages](https://thoughtbot.github.io/superglue).
|
27
|
+
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
Thank you, [contributors]!
|
31
|
+
|
32
|
+
[contributors]: https://github.com/thoughtbot/superglue_rails/graphs/contributors
|
@@ -16,6 +16,8 @@ module Superglue
|
|
16
16
|
remove_file "#{app_js_path}/application.js"
|
17
17
|
|
18
18
|
use_typescript = options["typescript"]
|
19
|
+
copy_erb_files
|
20
|
+
|
19
21
|
if use_typescript
|
20
22
|
copy_ts_files
|
21
23
|
else
|
@@ -31,6 +33,9 @@ module Superglue
|
|
31
33
|
say "Adding required member methods to ApplicationRecord"
|
32
34
|
add_member_methods
|
33
35
|
|
36
|
+
say "Enabling jsx rendering defaults"
|
37
|
+
insert_jsx_rendering_defaults
|
38
|
+
|
34
39
|
say "Installing Superglue and friends"
|
35
40
|
run "yarn add react react-dom @reduxjs/toolkit react-redux @thoughtbot/superglue"
|
36
41
|
|
@@ -43,6 +48,45 @@ module Superglue
|
|
43
48
|
|
44
49
|
private
|
45
50
|
|
51
|
+
def insert_jsx_rendering_defaults
|
52
|
+
inject_into_file "app/controllers/application_controller.rb", after: "class ApplicationController < ActionController::Base\n" do
|
53
|
+
<<-RUBY
|
54
|
+
# Enables Superglue rendering defaults for sensible view directories.
|
55
|
+
#
|
56
|
+
# without `use_jsx_rendering_defaults`:
|
57
|
+
#
|
58
|
+
# ```
|
59
|
+
# app/views/posts/
|
60
|
+
# - index.jsx
|
61
|
+
# - index.json.props
|
62
|
+
# - index.html.erb
|
63
|
+
# ```
|
64
|
+
#
|
65
|
+
# with `use_jsx_rendering_defaults`:
|
66
|
+
#
|
67
|
+
# ```
|
68
|
+
# app/views/posts/
|
69
|
+
# - index.jsx
|
70
|
+
# - index.json.props
|
71
|
+
# ```
|
72
|
+
#
|
73
|
+
# before_action :use_jsx_rendering_defaults
|
74
|
+
#
|
75
|
+
#
|
76
|
+
# The html template used when `use_jsx_rendering_defaults` is enabled.
|
77
|
+
# Defaults to "application/superglue".
|
78
|
+
#
|
79
|
+
# superglue_template "application/superglue"
|
80
|
+
|
81
|
+
RUBY
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def copy_erb_files
|
86
|
+
say "Copying superglue.html.erb file to app/views/application/"
|
87
|
+
copy_file "#{__dir__}/templates/erb/superglue.html.erb", "app/views/application/superglue.html.erb"
|
88
|
+
end
|
89
|
+
|
46
90
|
def copy_ts_files
|
47
91
|
say "Copying application.tsx file to #{app_js_path}"
|
48
92
|
copy_file "#{__dir__}/templates/ts/application.tsx", "#{app_js_path}/application.tsx"
|
@@ -7,14 +7,25 @@
|
|
7
7
|
* There is no style and structured with bare necessities. You should modify
|
8
8
|
* these components to fit your design needs.
|
9
9
|
*/
|
10
|
-
import React, { useContext, createContext, useMemo } from
|
11
|
-
export const ValidationContext = createContext({})
|
12
|
-
export const
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
}
|
10
|
+
import React, { useContext, createContext, useMemo } from 'react'
|
11
|
+
export const ValidationContext = createContext({})
|
12
|
+
export const useErrorMessage = (errorKey) => {
|
13
|
+
const errors = useContext(ValidationContext)
|
14
|
+
return useMemo(() => {
|
15
|
+
if (!errorKey) {
|
16
|
+
return null
|
17
|
+
}
|
18
|
+
const validationError = errors[errorKey]
|
19
|
+
const hasErrors = errorKey && validationError
|
20
|
+
if (!hasErrors) {
|
21
|
+
return null
|
22
|
+
}
|
23
|
+
const errorMessages = Array.isArray(validationError)
|
24
|
+
? validationError
|
25
|
+
: [validationError]
|
26
|
+
return errorMessages.join(' ')
|
27
|
+
}, [errors, errorKey])
|
28
|
+
}
|
18
29
|
/**
|
19
30
|
* Extras renders the hidden inputs generated by form_props.
|
20
31
|
*
|
@@ -22,10 +33,12 @@ export const useErrorKeyValidation = ({ errorKey, }) => {
|
|
22
33
|
* utf8, crsf_token, _method
|
23
34
|
*/
|
24
35
|
export const Extras = (hiddenInputAttributes) => {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
const hiddenProps = Object.values(hiddenInputAttributes)
|
37
|
+
const hiddenInputs = hiddenProps.map((props) => (
|
38
|
+
<input {...props} type="hidden" key={props.name} />
|
39
|
+
))
|
40
|
+
return <>{hiddenInputs}</>
|
41
|
+
}
|
29
42
|
/**
|
30
43
|
* A basic form component that supports inline errors.
|
31
44
|
*
|
@@ -33,13 +46,15 @@ export const Extras = (hiddenInputAttributes) => {
|
|
33
46
|
* Rails forms are generated.
|
34
47
|
*/
|
35
48
|
export const Form = ({ extras, validationErrors = {}, children, ...props }) => {
|
36
|
-
|
49
|
+
return (
|
50
|
+
<form {...props}>
|
37
51
|
<ValidationContext.Provider value={validationErrors}>
|
38
52
|
<Extras {...extras}></Extras>
|
39
53
|
{children}
|
40
54
|
</ValidationContext.Provider>
|
41
|
-
</form>
|
42
|
-
|
55
|
+
</form>
|
56
|
+
)
|
57
|
+
}
|
43
58
|
/**
|
44
59
|
* An inline error component.
|
45
60
|
*
|
@@ -47,84 +62,110 @@ export const Form = ({ extras, validationErrors = {}, children, ...props }) => {
|
|
47
62
|
* Please modify this to your liking.
|
48
63
|
*/
|
49
64
|
export const FieldError = ({ errorKey }) => {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
}
|
54
|
-
const validationError = errors[errorKey];
|
55
|
-
const hasErrors = errorKey && validationError;
|
56
|
-
if (!hasErrors) {
|
57
|
-
return null;
|
58
|
-
}
|
59
|
-
const errorMessages = Array.isArray(validationError)
|
60
|
-
? validationError
|
61
|
-
: [validationError];
|
62
|
-
return <span>{errorMessages.join(" ")}</span>;
|
63
|
-
};
|
65
|
+
const errorMessage = useErrorMessage(errorKey)
|
66
|
+
return <span>{errorMessage}</span>
|
67
|
+
}
|
64
68
|
/**
|
65
69
|
* A Field component.
|
66
70
|
*
|
67
71
|
* Combines a label, input and a FieldError. Please modify this to your liking.
|
68
72
|
*/
|
69
73
|
export const FieldBase = ({ label, errorKey, children, ...props }) => {
|
70
|
-
|
74
|
+
return (
|
75
|
+
<>
|
71
76
|
<label htmlFor={props.id}>{label}</label>
|
72
|
-
{children || <input {...props}/>}
|
73
|
-
<FieldError errorKey={errorKey}/>
|
74
|
-
</>
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
{children || <input {...props} />}
|
78
|
+
<FieldError errorKey={errorKey} />
|
79
|
+
</>
|
80
|
+
)
|
81
|
+
}
|
82
|
+
export const Checkbox = ({
|
83
|
+
type: _type,
|
84
|
+
includeHidden,
|
85
|
+
uncheckedValue,
|
86
|
+
errorKey,
|
87
|
+
...rest
|
88
|
+
}) => {
|
89
|
+
const { name } = rest
|
90
|
+
return (
|
91
|
+
<FieldBase {...rest} errorKey={errorKey}>
|
92
|
+
{includeHidden && (
|
93
|
+
<input
|
94
|
+
type="hidden"
|
95
|
+
name={name}
|
96
|
+
defaultValue={uncheckedValue}
|
97
|
+
autoComplete="off"
|
98
|
+
/>
|
99
|
+
)}
|
80
100
|
<input type="checkbox" {...rest}></input>
|
81
|
-
</FieldBase>
|
82
|
-
|
101
|
+
</FieldBase>
|
102
|
+
)
|
103
|
+
}
|
83
104
|
/**
|
84
105
|
* A collection checkbox component.
|
85
106
|
*
|
86
107
|
* Designed to work with a payload form_props's [collection_check_boxes helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#collection-select).
|
87
108
|
* Mimics the rails equivalent. Please modify to your liking.
|
88
109
|
*/
|
89
|
-
export const CollectionCheckboxes = ({
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
110
|
+
export const CollectionCheckboxes = ({
|
111
|
+
includeHidden,
|
112
|
+
collection,
|
113
|
+
label,
|
114
|
+
errorKey,
|
115
|
+
}) => {
|
116
|
+
if (collection.length == 0) {
|
117
|
+
return null
|
118
|
+
}
|
119
|
+
const checkboxes = collection.map((options) => {
|
120
|
+
return <Checkbox {...options} key={options.id} />
|
121
|
+
})
|
122
|
+
const { name } = collection[0]
|
123
|
+
return (
|
124
|
+
<>
|
125
|
+
{includeHidden && (
|
126
|
+
<input type="hidden" name={name} defaultValue={''} autoComplete="off" />
|
127
|
+
)}
|
99
128
|
<label>{label}</label>
|
100
129
|
{checkboxes}
|
101
|
-
<FieldError errorKey={errorKey}/>
|
102
|
-
</>
|
103
|
-
|
130
|
+
<FieldError errorKey={errorKey} />
|
131
|
+
</>
|
132
|
+
)
|
133
|
+
}
|
104
134
|
/**
|
105
135
|
* A collection radio button component.
|
106
136
|
*
|
107
137
|
* Designed to work with a payload form_props's [collection_radio_buttons helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#collection-select).
|
108
138
|
* Mimics the rails equivalent. Please modify to your liking.
|
109
139
|
*/
|
110
|
-
export const CollectionRadioButtons = ({
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
140
|
+
export const CollectionRadioButtons = ({
|
141
|
+
includeHidden,
|
142
|
+
collection,
|
143
|
+
label,
|
144
|
+
errorKey,
|
145
|
+
}) => {
|
146
|
+
if (collection.length == 0) {
|
147
|
+
return null
|
148
|
+
}
|
149
|
+
const radioButtons = collection.map((options) => {
|
150
|
+
return (
|
151
|
+
<div key={options.value}>
|
152
|
+
<input {...options} type="radio" />
|
117
153
|
<label htmlFor={options.id}>{options.label}</label>
|
118
|
-
</div>
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
154
|
+
</div>
|
155
|
+
)
|
156
|
+
})
|
157
|
+
const { name } = collection[0]
|
158
|
+
return (
|
159
|
+
<>
|
160
|
+
{includeHidden && (
|
161
|
+
<input type="hidden" name={name} defaultValue={''} autoComplete="off" />
|
162
|
+
)}
|
123
163
|
<label>{label}</label>
|
124
164
|
{radioButtons}
|
125
|
-
<FieldError errorKey={errorKey}/>
|
126
|
-
</>
|
127
|
-
|
165
|
+
<FieldError errorKey={errorKey} />
|
166
|
+
</>
|
167
|
+
)
|
168
|
+
}
|
128
169
|
/**
|
129
170
|
* A text field component.
|
130
171
|
*
|
@@ -132,8 +173,8 @@ export const CollectionRadioButtons = ({ includeHidden, collection, label, error
|
|
132
173
|
* Mimics the rails equivalent. Please modify to your liking.
|
133
174
|
*/
|
134
175
|
export const TextField = ({ type: _type, ...rest }) => {
|
135
|
-
|
136
|
-
}
|
176
|
+
return <FieldBase {...rest} type="text" />
|
177
|
+
}
|
137
178
|
/**
|
138
179
|
* A email field component.
|
139
180
|
*
|
@@ -141,8 +182,8 @@ export const TextField = ({ type: _type, ...rest }) => {
|
|
141
182
|
* Mimics the rails equivalent. Please modify to your liking.
|
142
183
|
*/
|
143
184
|
export const EmailField = ({ type: _type, ...rest }) => {
|
144
|
-
|
145
|
-
}
|
185
|
+
return <FieldBase {...rest} type="email" />
|
186
|
+
}
|
146
187
|
/**
|
147
188
|
* A color field component.
|
148
189
|
*
|
@@ -150,8 +191,8 @@ export const EmailField = ({ type: _type, ...rest }) => {
|
|
150
191
|
* Mimics the rails equivalent. Please modify to your liking.
|
151
192
|
*/
|
152
193
|
export const ColorField = ({ type: _type, ...rest }) => {
|
153
|
-
|
154
|
-
}
|
194
|
+
return <FieldBase {...rest} type="color" />
|
195
|
+
}
|
155
196
|
/**
|
156
197
|
* A date field component.
|
157
198
|
*
|
@@ -159,8 +200,8 @@ export const ColorField = ({ type: _type, ...rest }) => {
|
|
159
200
|
* Mimics the rails equivalent. Please modify to your liking.
|
160
201
|
*/
|
161
202
|
export const DateField = ({ type: _type, ...rest }) => {
|
162
|
-
|
163
|
-
}
|
203
|
+
return <FieldBase {...rest} type="date" />
|
204
|
+
}
|
164
205
|
/**
|
165
206
|
* A date field component.
|
166
207
|
*
|
@@ -168,8 +209,8 @@ export const DateField = ({ type: _type, ...rest }) => {
|
|
168
209
|
* Mimics the rails equivalent. Please modify to your liking.
|
169
210
|
*/
|
170
211
|
export const DateTimeLocalField = ({ type: _type, ...rest }) => {
|
171
|
-
|
172
|
-
}
|
212
|
+
return <FieldBase {...rest} type="datetime-local" />
|
213
|
+
}
|
173
214
|
/**
|
174
215
|
* A search field component.
|
175
216
|
*
|
@@ -177,8 +218,8 @@ export const DateTimeLocalField = ({ type: _type, ...rest }) => {
|
|
177
218
|
* Mimics the rails equivalent. Please modify to your liking.
|
178
219
|
*/
|
179
220
|
export const SearchField = ({ type: _type, ...rest }) => {
|
180
|
-
|
181
|
-
}
|
221
|
+
return <FieldBase {...rest} type="search" />
|
222
|
+
}
|
182
223
|
/**
|
183
224
|
* A tel field component.
|
184
225
|
*
|
@@ -186,8 +227,8 @@ export const SearchField = ({ type: _type, ...rest }) => {
|
|
186
227
|
* Mimics the rails equivalent. Please modify to your liking.
|
187
228
|
*/
|
188
229
|
export const TelField = ({ type: _type, ...rest }) => {
|
189
|
-
|
190
|
-
}
|
230
|
+
return <FieldBase {...rest} type="tel" />
|
231
|
+
}
|
191
232
|
/**
|
192
233
|
* A url field component.
|
193
234
|
*
|
@@ -195,8 +236,8 @@ export const TelField = ({ type: _type, ...rest }) => {
|
|
195
236
|
* Mimics the rails equivalent. Please modify to your liking.
|
196
237
|
*/
|
197
238
|
export const UrlField = ({ type: _type, ...rest }) => {
|
198
|
-
|
199
|
-
}
|
239
|
+
return <FieldBase {...rest} type="url" />
|
240
|
+
}
|
200
241
|
/**
|
201
242
|
* A month field component.
|
202
243
|
*
|
@@ -204,17 +245,17 @@ export const UrlField = ({ type: _type, ...rest }) => {
|
|
204
245
|
* Mimics the rails equivalent. Please modify to your liking.
|
205
246
|
*/
|
206
247
|
export const MonthField = ({ type: _type, ...rest }) => {
|
207
|
-
|
208
|
-
}
|
248
|
+
return <FieldBase {...rest} type="month" />
|
249
|
+
}
|
209
250
|
/**
|
210
|
-
* A
|
251
|
+
* A time field component.
|
211
252
|
*
|
212
253
|
* Designed to work with a payload form_props's [month_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#date-helpers).
|
213
254
|
* Mimics the rails equivalent. Please modify to your liking.
|
214
255
|
*/
|
215
256
|
export const TimeField = ({ type: _type, ...rest }) => {
|
216
|
-
|
217
|
-
}
|
257
|
+
return <FieldBase {...rest} type="time" />
|
258
|
+
}
|
218
259
|
/**
|
219
260
|
* A number field component.
|
220
261
|
*
|
@@ -222,8 +263,8 @@ export const TimeField = ({ type: _type, ...rest }) => {
|
|
222
263
|
* Mimics the rails equivalent. Please modify to your liking.
|
223
264
|
*/
|
224
265
|
export const NumberField = ({ type: _type, ...rest }) => {
|
225
|
-
|
226
|
-
}
|
266
|
+
return <FieldBase {...rest} type="number" />
|
267
|
+
}
|
227
268
|
/**
|
228
269
|
* A range field component.
|
229
270
|
*
|
@@ -231,8 +272,8 @@ export const NumberField = ({ type: _type, ...rest }) => {
|
|
231
272
|
* Mimics the rails equivalent. Please modify to your liking.
|
232
273
|
*/
|
233
274
|
export const RangeField = ({ type: _type, ...rest }) => {
|
234
|
-
|
235
|
-
}
|
275
|
+
return <FieldBase {...rest} type="range" />
|
276
|
+
}
|
236
277
|
/**
|
237
278
|
* A password field component.
|
238
279
|
*
|
@@ -240,8 +281,8 @@ export const RangeField = ({ type: _type, ...rest }) => {
|
|
240
281
|
* Mimics the rails equivalent. Please modify to your liking.
|
241
282
|
*/
|
242
283
|
export const PasswordField = ({ type: _type, ...rest }) => {
|
243
|
-
|
244
|
-
}
|
284
|
+
return <FieldBase {...rest} type="password" />
|
285
|
+
}
|
245
286
|
/**
|
246
287
|
* A select component.
|
247
288
|
*
|
@@ -250,26 +291,46 @@ export const PasswordField = ({ type: _type, ...rest }) => {
|
|
250
291
|
*
|
251
292
|
* Please modify to your liking.
|
252
293
|
*/
|
253
|
-
export const Select = ({
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
{
|
270
|
-
|
271
|
-
|
272
|
-
}
|
294
|
+
export const Select = ({
|
295
|
+
includeHidden,
|
296
|
+
name,
|
297
|
+
id,
|
298
|
+
children,
|
299
|
+
options,
|
300
|
+
label,
|
301
|
+
errorKey,
|
302
|
+
multiple,
|
303
|
+
type: _type,
|
304
|
+
...rest
|
305
|
+
}) => {
|
306
|
+
const addHidden = includeHidden && multiple
|
307
|
+
const optionElements = options.map((item) => {
|
308
|
+
if ('options' in item) {
|
309
|
+
return (
|
310
|
+
<optgroup label={item.label} key={item.label}>
|
311
|
+
{item.options.map((opt) => (
|
312
|
+
<option key={opt.label} {...opt} />
|
313
|
+
))}
|
314
|
+
</optgroup>
|
315
|
+
)
|
316
|
+
} else {
|
317
|
+
return <option key={item.label} {...item} />
|
318
|
+
}
|
319
|
+
})
|
320
|
+
return (
|
321
|
+
<>
|
322
|
+
{addHidden && (
|
323
|
+
<input type="hidden" name={name} value={''} autoComplete="off" />
|
324
|
+
)}
|
325
|
+
<FieldBase label={label} errorKey={errorKey} id={id}>
|
326
|
+
<select name={name} id={id} multiple={multiple} {...rest}>
|
327
|
+
{children}
|
328
|
+
{optionElements}
|
329
|
+
</select>
|
330
|
+
</FieldBase>
|
331
|
+
</>
|
332
|
+
)
|
333
|
+
}
|
273
334
|
/**
|
274
335
|
* A text area component.
|
275
336
|
*
|
@@ -277,11 +338,13 @@ export const Select = ({ includeHidden, name, id, children, options, multiple, t
|
|
277
338
|
* Mimics the rails equivalent. Please modify to your liking.
|
278
339
|
*/
|
279
340
|
export const TextArea = ({ type: _type, errorKey, ...rest }) => {
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
341
|
+
const { label } = rest
|
342
|
+
return (
|
343
|
+
<FieldBase label={label} errorKey={errorKey} id={rest.id}>
|
344
|
+
<textarea {...rest} />
|
345
|
+
</FieldBase>
|
346
|
+
)
|
347
|
+
}
|
285
348
|
/**
|
286
349
|
* A file field component.
|
287
350
|
*
|
@@ -289,8 +352,8 @@ export const TextArea = ({ type: _type, errorKey, ...rest }) => {
|
|
289
352
|
* Mimics the rails equivalent. Please modify to your liking.
|
290
353
|
*/
|
291
354
|
export const FileField = ({ type: _type, ...rest }) => {
|
292
|
-
|
293
|
-
}
|
355
|
+
return <FieldBase {...rest} type="file" />
|
356
|
+
}
|
294
357
|
/**
|
295
358
|
* A SubmitButton component.
|
296
359
|
*
|
@@ -298,5 +361,10 @@ export const FileField = ({ type: _type, ...rest }) => {
|
|
298
361
|
* Mimics the rails equivalent. Please modify to your liking.
|
299
362
|
*/
|
300
363
|
export const SubmitButton = ({ type: _type, text, ...rest }) => {
|
301
|
-
|
302
|
-
}
|
364
|
+
return (
|
365
|
+
<button {...rest} type="submit">
|
366
|
+
{' '}
|
367
|
+
{text}{' '}
|
368
|
+
</button>
|
369
|
+
)
|
370
|
+
}
|