proscenium 0.19.0.beta4-x86_64-linux → 0.19.0.beta5-x86_64-linux
Sign up to get free protection for your applications and to get access to all the features.
- 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
|