proscenium 0.19.0.beta4-x86_64-linux → 0.19.0.beta5-x86_64-linux
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 +1 -1
- data/lib/proscenium/builder.rb +9 -13
- data/lib/proscenium/ext/proscenium +0 -0
- data/lib/proscenium/importer.rb +13 -13
- data/lib/proscenium/middleware/base.rb +0 -2
- data/lib/proscenium/middleware/engines.rb +5 -9
- data/lib/proscenium/middleware/esbuild.rb +13 -8
- data/lib/proscenium/middleware.rb +2 -4
- data/lib/proscenium/railtie.rb +6 -3
- data/lib/proscenium/react_componentable.rb +1 -1
- data/lib/proscenium/resolver.rb +3 -8
- data/lib/proscenium/side_load.rb +1 -1
- data/lib/proscenium/ui/flash/index.css +1 -0
- data/lib/proscenium/ui/flash/index.js +73 -0
- data/lib/proscenium/ui/flash.rb +15 -0
- data/lib/proscenium/ui/form/field_methods.rb +88 -0
- data/lib/proscenium/ui/form/fields/base.rb +188 -0
- data/lib/proscenium/ui/form/fields/checkbox/index.jsx +48 -0
- data/lib/proscenium/ui/form/fields/checkbox/index.module.css +9 -0
- data/lib/proscenium/ui/form/fields/checkbox/previews/basic.jsx +8 -0
- data/lib/proscenium/ui/form/fields/checkbox.rb +32 -0
- data/lib/proscenium/ui/form/fields/date.module.css +27 -0
- data/lib/proscenium/ui/form/fields/datetime.rb +15 -0
- data/lib/proscenium/ui/form/fields/hidden.rb +9 -0
- data/lib/proscenium/ui/form/fields/input/index.jsx +71 -0
- data/lib/proscenium/ui/form/fields/input/index.module.css +13 -0
- data/lib/proscenium/ui/form/fields/input/previews/basic.jsx +8 -0
- data/lib/proscenium/ui/form/fields/input.rb +14 -0
- data/lib/proscenium/ui/form/fields/radio_group.rb +173 -0
- data/lib/proscenium/ui/form/fields/radio_input/index.jsx +44 -0
- data/lib/proscenium/ui/form/fields/radio_input/index.module.css +13 -0
- data/lib/proscenium/ui/form/fields/radio_input/previews/basic.jsx +8 -0
- data/lib/proscenium/ui/form/fields/radio_input.rb +17 -0
- data/lib/proscenium/ui/form/fields/rich_textarea.css +23 -0
- data/lib/proscenium/ui/form/fields/rich_textarea.js +6 -0
- data/lib/proscenium/ui/form/fields/rich_textarea.rb +18 -0
- data/lib/proscenium/ui/form/fields/select.jsx +47 -0
- data/lib/proscenium/ui/form/fields/select.module.css +46 -0
- data/lib/proscenium/ui/form/fields/select.rb +300 -0
- data/lib/proscenium/ui/form/fields/tel.css +297 -0
- data/lib/proscenium/ui/form/fields/tel.js +83 -0
- data/lib/proscenium/ui/form/fields/tel.rb +54 -0
- data/lib/proscenium/ui/form/fields/textarea/index.jsx +50 -0
- data/lib/proscenium/ui/form/fields/textarea/index.module.css +13 -0
- data/lib/proscenium/ui/form/fields/textarea/previews/basic.jsx +8 -0
- data/lib/proscenium/ui/form/fields/textarea.rb +18 -0
- data/lib/proscenium/ui/form/translation.rb +71 -0
- data/lib/proscenium/ui/form.css +52 -0
- data/lib/proscenium/ui/form.rb +213 -0
- data/lib/proscenium/ui/props.css +7 -0
- data/lib/proscenium/ui/react-manager/index.jsx +1 -1
- data/lib/proscenium/ui/test.js +1 -1
- data/lib/proscenium/ui/ujs/index.js +1 -1
- data/lib/proscenium/ui.rb +3 -0
- data/lib/proscenium/utils.rb +33 -0
- data/lib/proscenium/version.rb +1 -1
- data/lib/proscenium/view_component.rb +0 -2
- data/lib/proscenium.rb +12 -2
- metadata +61 -10
- data/lib/proscenium/middleware/runtime.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27b529fbf329a6849b5c834fcfcf12599d5edc059cca2f0d56bb3269a480fb60
|
4
|
+
data.tar.gz: 7d7386041b2ddb41ddf440804637f69cb18cdd6250f8d0cc0ac30c3174c7a79d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59dd253f7547786da13424a4696310b64d1d05fe03a3acaa6592c0b0bdecb91d8dd05a0ac44a021c84a9fca687888236cbbb84ed28058fbf87452c8d29748cd5
|
7
|
+
data.tar.gz: 181c82159899d0f4b2ce659f0d49e86c45e79c5340d9141dba7c135f8b3ea191d8b10a2261f8117e12fd2a554a71fd8116a5e62a06ecb36e9f9b1e56bdfe1d23
|
data/README.md
CHANGED
@@ -413,7 +413,7 @@ if (typeof proscenium.env?.UNKNOWN !== "undefined") {
|
|
413
413
|
Basic support is provided for importing your Rails locale files from `config/locales/*.yml`, exporting them as JSON.
|
414
414
|
|
415
415
|
```js
|
416
|
-
import translations from "
|
416
|
+
import translations from "proscenium/i18n";
|
417
417
|
// translations.en.*
|
418
418
|
```
|
419
419
|
|
data/lib/proscenium/builder.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'ffi'
|
4
|
-
require 'oj'
|
5
4
|
|
6
5
|
module Proscenium
|
7
6
|
class Builder
|
@@ -42,7 +41,7 @@ module Proscenium
|
|
42
41
|
attr_reader :error
|
43
42
|
|
44
43
|
def initialize(error)
|
45
|
-
@error =
|
44
|
+
@error = JSON.parse(error, strict: true).deep_transform_keys(&:underscore)
|
46
45
|
|
47
46
|
msg = @error['text']
|
48
47
|
if (location = @error['location'])
|
@@ -65,8 +64,8 @@ module Proscenium
|
|
65
64
|
new(root:).build_to_path(path)
|
66
65
|
end
|
67
66
|
|
68
|
-
def self.build_to_string(path, root: nil)
|
69
|
-
new(root:).build_to_string(path)
|
67
|
+
def self.build_to_string(path, root: nil, bundle: nil)
|
68
|
+
new(root:, bundle:).build_to_string(path)
|
70
69
|
end
|
71
70
|
|
72
71
|
def self.resolve(path, root: nil)
|
@@ -78,15 +77,18 @@ module Proscenium
|
|
78
77
|
Request.reset_config
|
79
78
|
end
|
80
79
|
|
81
|
-
def initialize(root: nil)
|
80
|
+
def initialize(root: nil, bundle: nil)
|
81
|
+
bundle = Proscenium.config.bundle if bundle.nil?
|
82
|
+
|
82
83
|
@request_config = FFI::MemoryPointer.from_string({
|
83
84
|
RootPath: (root || Rails.root).to_s,
|
84
85
|
GemPath: gem_root,
|
85
86
|
Environment: ENVIRONMENTS.fetch(Rails.env.to_sym, 2),
|
86
|
-
Engines: engines,
|
87
|
+
Engines: Proscenium.config.engines,
|
87
88
|
EnvVars: env_vars,
|
88
89
|
CodeSplitting: Proscenium.config.code_splitting,
|
89
|
-
|
90
|
+
ExternalNodeModules: Proscenium.config.external_node_modules,
|
91
|
+
Bundle: bundle,
|
90
92
|
Debug: Proscenium.config.debug
|
91
93
|
}.to_json)
|
92
94
|
end
|
@@ -139,12 +141,6 @@ module Proscenium
|
|
139
141
|
q ? "--cache-query-string #{q}" : nil
|
140
142
|
end
|
141
143
|
|
142
|
-
def engines
|
143
|
-
Proscenium.config.engines.to_h { |e| [e.engine_name, e.root.to_s] }.tap do |x|
|
144
|
-
x['proscenium/ui'] = Proscenium.ui_path.to_s
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
144
|
def gem_root
|
149
145
|
Pathname.new(__dir__).join('..', '..').to_s
|
150
146
|
end
|
Binary file
|
data/lib/proscenium/importer.rb
CHANGED
@@ -67,28 +67,28 @@ module Proscenium
|
|
67
67
|
sideload_css(filepath, **options) unless options[:css] == false
|
68
68
|
end
|
69
69
|
|
70
|
-
def sideload_js(filepath, **
|
71
|
-
|
72
|
-
|
73
|
-
filepath = Rails.root.join(filepath) unless filepath.is_a?(Pathname)
|
74
|
-
filepath = filepath.sub_ext('')
|
70
|
+
def sideload_js(filepath, **)
|
71
|
+
_sideload(filepath, JS_EXTENSIONS, **)
|
72
|
+
end
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
import(Resolver.resolve(fp.to_s), sideloaded: true, **options)
|
79
|
-
end
|
80
|
-
end
|
74
|
+
def sideload_css(filepath, **)
|
75
|
+
_sideload(filepath, CSS_EXTENSIONS, **)
|
81
76
|
end
|
82
77
|
|
83
|
-
def
|
78
|
+
private def _sideload(filepath, extensions, **options) # rubocop:disable Style/AccessModifierDeclarations
|
84
79
|
return unless Proscenium.config.side_load
|
85
80
|
|
86
81
|
filepath = Rails.root.join(filepath) unless filepath.is_a?(Pathname)
|
87
82
|
filepath = filepath.sub_ext('')
|
88
83
|
|
89
|
-
|
84
|
+
extensions.find do |x|
|
90
85
|
if (fp = filepath.sub_ext(x)).exist?
|
91
|
-
|
86
|
+
if (fp = fp.to_s).start_with?(Proscenium.ui_path.to_s)
|
87
|
+
fp.sub!(Proscenium.ui_path_regex, 'proscenium/')
|
88
|
+
import(Resolver.resolve(fp), sideloaded: true, **options)
|
89
|
+
else
|
90
|
+
import(Resolver.resolve(fp.to_s), sideloaded: true, **options)
|
91
|
+
end
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
@@ -10,7 +10,7 @@ module Proscenium
|
|
10
10
|
#
|
11
11
|
# module Gem1
|
12
12
|
# class Engine < ::Rails::Engine
|
13
|
-
# config.proscenium.engines
|
13
|
+
# config.proscenium.engines['gem1'] = root
|
14
14
|
# end
|
15
15
|
# end
|
16
16
|
#
|
@@ -24,21 +24,17 @@ module Proscenium
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def root_for_readable
|
27
|
-
|
27
|
+
engine.last
|
28
28
|
end
|
29
29
|
|
30
30
|
def engine
|
31
|
-
@engine ||= Proscenium.config.engines.find do |
|
32
|
-
@request.path.start_with?("/#{
|
31
|
+
@engine ||= Proscenium.config.engines.find do |k, _|
|
32
|
+
@request.path.start_with?("/#{k}")
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
def engine_name
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def ui?
|
41
|
-
@request.path.start_with?('/proscenium/ui/')
|
37
|
+
engine.first
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
@@ -6,21 +6,26 @@ module Proscenium
|
|
6
6
|
class CompileError < Base::CompileError
|
7
7
|
def initialize(args)
|
8
8
|
detail = args[:detail]
|
9
|
-
detail =
|
9
|
+
detail = JSON.parse(detail, mode: :strict)
|
10
10
|
|
11
|
-
args[
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
args['detail'] = if detail['location']
|
12
|
+
"#{detail['text']} in #{detail['location']['file']}:" +
|
13
|
+
detail['location']['line'].to_s
|
14
|
+
else
|
15
|
+
detail['text']
|
16
|
+
end
|
17
17
|
|
18
18
|
super
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def attempt
|
23
|
-
|
23
|
+
bundle = nil
|
24
|
+
if Proscenium.config.external_node_modules && path_to_build.start_with?('node_modules/')
|
25
|
+
bundle = false
|
26
|
+
end
|
27
|
+
|
28
|
+
render_response Builder.build_to_string(path_to_build, bundle:)
|
24
29
|
rescue Builder::CompileError => e
|
25
30
|
raise self.class::CompileError, { file: @request.fullpath, detail: e.message }, caller
|
26
31
|
end
|
@@ -10,7 +10,6 @@ module Proscenium
|
|
10
10
|
autoload :Base
|
11
11
|
autoload :Esbuild
|
12
12
|
autoload :Engines
|
13
|
-
autoload :Runtime
|
14
13
|
|
15
14
|
def initialize(app)
|
16
15
|
@app = app
|
@@ -40,7 +39,6 @@ module Proscenium
|
|
40
39
|
end
|
41
40
|
|
42
41
|
def find_type(request)
|
43
|
-
return Runtime if request.path.match?(%r{^/@proscenium/})
|
44
42
|
return Esbuild if Pathname.new(request.path).fnmatch?(app_path_glob, File::FNM_EXTGLOB)
|
45
43
|
|
46
44
|
pathname = Pathname.new(request.path)
|
@@ -53,12 +51,12 @@ module Proscenium
|
|
53
51
|
end
|
54
52
|
|
55
53
|
def engines_path_glob
|
56
|
-
names = Proscenium.config.engines.
|
54
|
+
names = Proscenium.config.engines.keys
|
57
55
|
"/{#{names.join(',')}}/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{file_extensions}}"
|
58
56
|
end
|
59
57
|
|
60
58
|
def ui_path_glob
|
61
|
-
"/proscenium
|
59
|
+
"/proscenium/**.{#{file_extensions}}"
|
62
60
|
end
|
63
61
|
|
64
62
|
def file_extensions
|
data/lib/proscenium/railtie.rb
CHANGED
@@ -14,6 +14,7 @@ module Proscenium
|
|
14
14
|
config.proscenium.bundle = true
|
15
15
|
config.proscenium.side_load = true
|
16
16
|
config.proscenium.code_splitting = true
|
17
|
+
config.proscenium.external_node_modules = false
|
17
18
|
|
18
19
|
# Cache asset paths when building to path. Enabled by default in production.
|
19
20
|
# @see Proscenium::Builder#build_to_path
|
@@ -36,9 +37,11 @@ module Proscenium
|
|
36
37
|
#
|
37
38
|
# Example:
|
38
39
|
# class Gem1::Engine < ::Rails::Engine
|
39
|
-
# config.proscenium.engines
|
40
|
+
# config.proscenium.engines[:gem1] = root
|
40
41
|
# end
|
41
|
-
config.proscenium.engines =
|
42
|
+
config.proscenium.engines = {
|
43
|
+
proscenium: Proscenium.ui_path
|
44
|
+
}
|
42
45
|
|
43
46
|
config.action_dispatch.rescue_templates = {
|
44
47
|
'Proscenium::Builder::BuildError' => 'build_error'
|
@@ -64,7 +67,7 @@ module Proscenium
|
|
64
67
|
end
|
65
68
|
|
66
69
|
initializer 'proscenium.middleware' do |app|
|
67
|
-
app.middleware.insert_after ActionDispatch::Static, Middleware
|
70
|
+
app.middleware.insert_after ActionDispatch::Static, Proscenium::Middleware
|
68
71
|
app.middleware.insert_after ActionDispatch::Static, Rack::ETag, 'no-cache'
|
69
72
|
app.middleware.insert_after ActionDispatch::Static, Rack::ConditionalGet
|
70
73
|
end
|
@@ -40,7 +40,7 @@ module Proscenium
|
|
40
40
|
class_attribute :loader
|
41
41
|
|
42
42
|
# @return [String] the URL path to the component manager.
|
43
|
-
class_attribute :manager, default: '
|
43
|
+
class_attribute :manager, default: '/proscenium/react-manager/index.jsx'
|
44
44
|
end
|
45
45
|
|
46
46
|
class_methods do
|
data/lib/proscenium/resolver.rb
CHANGED
@@ -11,8 +11,6 @@ module Proscenium
|
|
11
11
|
#
|
12
12
|
# @param path [String] Can be URL path, file system path, or bare specifier (ie. NPM package).
|
13
13
|
# @return [String] URL path.
|
14
|
-
#
|
15
|
-
# rubocop:disable Metrics/*
|
16
14
|
def self.resolve(path)
|
17
15
|
self.resolved ||= {}
|
18
16
|
|
@@ -21,12 +19,10 @@ module Proscenium
|
|
21
19
|
raise ArgumentError, 'path must be an absolute file system or URL path'
|
22
20
|
end
|
23
21
|
|
24
|
-
if path.start_with?('
|
22
|
+
if path.start_with?('proscenium/')
|
25
23
|
"/#{path}"
|
26
|
-
elsif path.start_with?
|
27
|
-
path.
|
28
|
-
elsif (engine = Proscenium.config.engines.find { |e| path.start_with? "#{e.root}/" })
|
29
|
-
path.sub(/^#{engine.root}/, "/#{engine.engine_name}")
|
24
|
+
elsif (engine = Proscenium.config.engines.find { |_, v| path.start_with? "#{v}/" })
|
25
|
+
path.sub(/^#{engine.last}/, "/#{engine.first}")
|
30
26
|
elsif path.start_with?("#{Rails.root}/")
|
31
27
|
path.delete_prefix Rails.root.to_s
|
32
28
|
else
|
@@ -34,6 +30,5 @@ module Proscenium
|
|
34
30
|
end
|
35
31
|
end
|
36
32
|
end
|
37
|
-
# rubocop:enable Metrics/*
|
38
33
|
end
|
39
34
|
end
|
data/lib/proscenium/side_load.rb
CHANGED
@@ -172,7 +172,7 @@ module Proscenium
|
|
172
172
|
end
|
173
173
|
|
174
174
|
# The reason why we sideload CSS after JS is because the order of CSS is important.
|
175
|
-
# Basically, the layout should be loaded before the view so that CSS cascading works
|
175
|
+
# Basically, the layout should be loaded before the view so that CSS cascading works in the
|
176
176
|
# right direction.
|
177
177
|
css_imports.reverse_each do |it|
|
178
178
|
Importer.sideload_css it, **options
|
@@ -0,0 +1 @@
|
|
1
|
+
@import "https://cdn.jsdelivr.net/npm/sourdough-toast/src/sourdough-toast.css";
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import domMutations from "https://esm.run/dom-mutations";
|
2
|
+
import { Sourdough, toast } from "https://esm.run/sourdough-toast";
|
3
|
+
|
4
|
+
class HueFlash extends HTMLElement {
|
5
|
+
static observedAttributes = ["data-flash-alert", "data-flash-notice"];
|
6
|
+
|
7
|
+
connectedCallback() {
|
8
|
+
this.#initSourdough();
|
9
|
+
}
|
10
|
+
|
11
|
+
async #initSourdough() {
|
12
|
+
if ("sourdoughBooted" in window) return;
|
13
|
+
|
14
|
+
const sourdough = new Sourdough({
|
15
|
+
richColors: true,
|
16
|
+
yPosition: "bottom",
|
17
|
+
xPosition: "center",
|
18
|
+
});
|
19
|
+
sourdough.boot();
|
20
|
+
window.sourdoughBooted = true;
|
21
|
+
|
22
|
+
// Watch for changes to htl:flashes meta tag
|
23
|
+
const flashesSelector = "meta[name='rails:flashes']";
|
24
|
+
for await (const mutation of domMutations(document.head, {
|
25
|
+
childList: true,
|
26
|
+
subtree: true,
|
27
|
+
attributes: true,
|
28
|
+
})) {
|
29
|
+
let $ele = null;
|
30
|
+
|
31
|
+
if (
|
32
|
+
mutation.type === "attributes" &&
|
33
|
+
mutation.target.nodeName == "META" &&
|
34
|
+
mutation.attributeName == "content"
|
35
|
+
) {
|
36
|
+
$ele = mutation.target;
|
37
|
+
} else if (mutation.type === "childList") {
|
38
|
+
for (const node of mutation.addedNodes) {
|
39
|
+
if (node.matches(flashesSelector)) {
|
40
|
+
$ele = node;
|
41
|
+
break;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
if ($ele) {
|
47
|
+
const flashes = JSON.parse($ele.getAttribute("content"));
|
48
|
+
for (const [type, message] of Object.entries(flashes)) {
|
49
|
+
if (type === "alert") {
|
50
|
+
toast.error(message);
|
51
|
+
} else if (type === "notice") {
|
52
|
+
toast.success(message);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
60
|
+
this.#initSourdough();
|
61
|
+
|
62
|
+
if (newValue === null) return;
|
63
|
+
|
64
|
+
if (name === "data-flash-alert") {
|
65
|
+
toast.warning(newValue);
|
66
|
+
} else if (name === "data-flash-notice") {
|
67
|
+
toast.success(newValue);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
!customElements.get("pui-flash") &&
|
73
|
+
customElements.define("pui-flash", HueFlash);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Proscenium::UI
|
4
|
+
class Flash < Component
|
5
|
+
register_element :pui_flash
|
6
|
+
|
7
|
+
def self.source_path
|
8
|
+
super / '../flash/index.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
def view_template
|
12
|
+
pui_flash data: { flash: helpers.flash.to_hash }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Proscenium::UI::Form
|
4
|
+
module FieldMethods
|
5
|
+
# Renders a hidden input field.
|
6
|
+
#
|
7
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
8
|
+
# @param attributes [Hash] passed through to each input
|
9
|
+
def hidden_field(*args, **)
|
10
|
+
render Fields::Hidden.new(args, @model, self, **)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
14
|
+
# @param attributes [Hash] passed through to each input
|
15
|
+
def rich_textarea_field(*args, **attributes)
|
16
|
+
merge_bang_attributes! args, attributes
|
17
|
+
render Fields::RichTextarea.new(args, @model, self, **attributes)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
21
|
+
# @param attributes [Hash] passed through to each input
|
22
|
+
def datetime_local_field(*args, **attributes)
|
23
|
+
merge_bang_attributes! args, attributes
|
24
|
+
render Fields::Datetime.new(args, @model, self, **attributes)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
28
|
+
# @param attributes [Hash] passed through to each input
|
29
|
+
def checkbox_field(*args, **attributes)
|
30
|
+
merge_bang_attributes! args, attributes
|
31
|
+
render Fields::Checkbox.new(args, @model, self, **attributes)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
35
|
+
# @param attributes [Hash] passed through to each input
|
36
|
+
def tel_field(*args, **attributes)
|
37
|
+
merge_bang_attributes! args, attributes
|
38
|
+
render Fields::Tel.new(args, @model, self, **attributes)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
42
|
+
# @param attributes [Hash] passed through to each input
|
43
|
+
def select_field(*args, **attributes, &)
|
44
|
+
merge_bang_attributes! args, attributes, additional_bang_attrs: [:typeahead]
|
45
|
+
render Fields::Select.new(args, @model, self, **attributes, &)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @see #select_field
|
49
|
+
def select_country_field(*args, **attributes)
|
50
|
+
merge_bang_attributes! args, attributes
|
51
|
+
attributes[:typeahead] = true
|
52
|
+
attributes[:options] = '/countries'
|
53
|
+
attributes[:component_props] = {
|
54
|
+
items_on_search: true,
|
55
|
+
input_props: { required: attributes.delete(:required) }
|
56
|
+
}
|
57
|
+
|
58
|
+
select_field(*args, **attributes)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Renders a <textarea> field for the given `attribute`.
|
62
|
+
#
|
63
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
64
|
+
# @param attributes [Hash] passed through to each input
|
65
|
+
def textarea_field(*args, **attributes)
|
66
|
+
merge_bang_attributes! args, attributes
|
67
|
+
render Fields::Textarea.new(args, @model, self, **attributes)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Renders a group of radio inputs for each option of the given `field`.
|
71
|
+
#
|
72
|
+
# @param args [Array<Symbol>] name or nested names of model attribute
|
73
|
+
# @param attributes [Hash] passed through to each input
|
74
|
+
def radio_group(*args, **attributes)
|
75
|
+
attributes[:options] = args.pop if args.last.is_a?(Array)
|
76
|
+
|
77
|
+
render Fields::RadioGroup.new(args, @model, self, **attributes)
|
78
|
+
end
|
79
|
+
|
80
|
+
def radio_field(...)
|
81
|
+
div { radio_input(...) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def radio_input(*args, **)
|
85
|
+
render Fields::RadioInput.new(args, @model, self, **)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|