asbru 0.0.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +204 -0
- data/Rakefile +27 -0
- data/lib/asbru.rb +5 -0
- data/lib/asbru/cml.rb +67 -0
- data/lib/asbru/components.rb +4 -0
- data/lib/asbru/components/sage.rb +48 -0
- data/lib/asbru/components/savage.rb +23 -0
- data/lib/asbru/form_builder.rb +214 -0
- data/lib/asbru/links.rb +29 -0
- data/lib/asbru/ragna.rb +15 -0
- data/lib/asbru/rails_helpers.rb +9 -0
- data/lib/asbru/railtie.rb +4 -0
- data/lib/asbru/version.rb +3 -0
- data/lib/asbru/view_helpers.rb +6 -0
- data/lib/tasks/asbru_tasks.rake +4 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: adbc029751ba4d56cc4fa21e754fdc1dbd4e7adf82fb69325623fbeb06243fb2
|
4
|
+
data.tar.gz: 19f3ed4cafb6cdde19827b9cdaa0ff5df9608fef2c9688c0f2ce17ccbcfe2e36
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 36d7cfc112787a88ee64c864275163c3721a13e6bbae0b2cc454088e342e34c137568fc1ebb964e107bec310ab3ee9deae08ae6c310e35f6c1e54c01d9f99a2e
|
7
|
+
data.tar.gz: b17440674f8b014ad3c081c77427240a76a989b84c37475724935cc42664ed37ef49b2edad21f1a6a5efae5cad29a760575362e07836889b651dfb84e805bd61
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2021 Stev-0
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
# Asbru
|
2
|
+
Asbru is meant as a bridge between Rails and React that (hopefully) allows us
|
3
|
+
to enjoy the perks of both ecosystems without having to write huge amounts of
|
4
|
+
boilerplate.
|
5
|
+
Meanwhile there is some added safety in the form of raises on loading
|
6
|
+
non-existing components, and syntactic sugar(less curlies and parens) in view
|
7
|
+
code AND there are some solutions for patterns of code use we notice.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'asbru'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
```bash
|
17
|
+
$ bundle
|
18
|
+
```
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
```bash
|
22
|
+
$ gem install asbru
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
Require 'asbru/ragna' and the C and CML modules are available everywhere.
|
27
|
+
Your application helper is a great place for the require as most code
|
28
|
+
that works in tandem with Asbru should go there.
|
29
|
+
|
30
|
+
in app/helpers/application_helper.rb
|
31
|
+
```ruby
|
32
|
+
require 'asbru/ragna'
|
33
|
+
|
34
|
+
module ApplicationHelper
|
35
|
+
include Asbru::RailsHelpers
|
36
|
+
...
|
37
|
+
end
|
38
|
+
|
39
|
+
```
|
40
|
+
|
41
|
+
Now you can use components in your rails views in `Savage` mode:
|
42
|
+
|
43
|
+
```erb
|
44
|
+
<%= C.layout_banner(
|
45
|
+
steps: [],
|
46
|
+
title: { color: 'light', text: t('dossier.overview.title') },
|
47
|
+
color: 'energized-500') %>
|
48
|
+
<%= C.ui_divider(
|
49
|
+
height: 60,
|
50
|
+
color: 'transparent',
|
51
|
+
hideMobileS: true) %>
|
52
|
+
|
53
|
+
<%= CML.vertical_spacer 10 %>
|
54
|
+
```
|
55
|
+
|
56
|
+
or in `Sage` mode:
|
57
|
+
|
58
|
+
```erb
|
59
|
+
<%= C::Layout.banner(color: 'energized-500',
|
60
|
+
title: { color: 'light', text: t('dossier.overview.title') }) %>
|
61
|
+
<%= C::Ui.divider(
|
62
|
+
height: 60,
|
63
|
+
color: 'transparent',
|
64
|
+
hideMobileS: true) %>
|
65
|
+
|
66
|
+
```
|
67
|
+
|
68
|
+
And you can write CML
|
69
|
+
```erb
|
70
|
+
<%= CML.h1 'Hello world!' %>
|
71
|
+
<%= CML.vertical_spacer 10 %>
|
72
|
+
<%= CML.p 'In the land where I was born.' %>
|
73
|
+
<%= CML.p 'Lives a man beneath the sea.' %>
|
74
|
+
<%= CML.p '...', color: 'stable-500' %>
|
75
|
+
```
|
76
|
+
|
77
|
+
|
78
|
+
## Lets take a deeper dive
|
79
|
+
|
80
|
+
When we open the rails console we can see that asbru has some benefits over
|
81
|
+
loading components just via react rails:
|
82
|
+
|
83
|
+
```irb
|
84
|
+
2.7.1 :001 > require 'asbru/components/sage'
|
85
|
+
2.7.1 :002 > C = Asbru::Components::Sage
|
86
|
+
2.7.1 :003 > C.constants
|
87
|
+
=> []
|
88
|
+
2.7.1 :004 > C.setup
|
89
|
+
2.7.1 :005 > C.constants
|
90
|
+
=> [:Layout, :Modal, :Progress, :Form, :Styles, :Ui, :Badge, :Button, :Table, :Text, :Card]
|
91
|
+
2.7.1 :006 >C::Ui.methods - Module.methods
|
92
|
+
=> [:image, :logo, :action_sheet, :icon, :divider, :icon_phone, :snackbar, :tooltip, :helper_implementation_class, :helper_implementation_class=, :react_component]
|
93
|
+
2.7.1 :007 > C::Ui.divider margin: 20
|
94
|
+
=> "<div data-react-class=\"ui.Divider\" data-react-props=\"{"margin":20}\" data-react-cache-id=\"ui.Divider-0\"></div>"
|
95
|
+
2.7.1 :008 > C::iU.divider margin: 20
|
96
|
+
Traceback (most recent call last):
|
97
|
+
2: from (irb):26
|
98
|
+
1: from (irb):27:in `rescue in irb_binding'
|
99
|
+
NameError (uninitialized constant Asbru::Components::Sage::Iu)
|
100
|
+
2.7.1 :009 > C::Ui.blarg margin: 20
|
101
|
+
Traceback (most recent call last):
|
102
|
+
1: from (irb):26
|
103
|
+
NoMethodError (undefined method `blarg' for Asbru::Components::Sage::Ui:Class)
|
104
|
+
```
|
105
|
+
|
106
|
+
We have a list of available folders and componentent available in Ruby and we
|
107
|
+
raise errors when we use the wrong wrong module or method names.
|
108
|
+
|
109
|
+
To use `Sage` a json file names /app/javascript/components/components.json is
|
110
|
+
required. This file can be generated with the following script. We have no
|
111
|
+
cannonical way of solving this yet and it requires certain best practices to be
|
112
|
+
followed during component development.
|
113
|
+
|
114
|
+
```js
|
115
|
+
#!/usr/bin/env node
|
116
|
+
|
117
|
+
const dirTree = require('directory-tree');
|
118
|
+
const fs = require('fs');
|
119
|
+
const tree = dirTree('./app/javascript/components', { extensions: /\.js$/ });
|
120
|
+
|
121
|
+
const components =
|
122
|
+
tree.children.length > 0
|
123
|
+
? tree.children
|
124
|
+
.map((child) => {
|
125
|
+
return {
|
126
|
+
folder: child.name,
|
127
|
+
components:
|
128
|
+
child.children.length > 0
|
129
|
+
? child.children
|
130
|
+
.filter((c) => c.type == 'directory')
|
131
|
+
.map((c) =>
|
132
|
+
c.name
|
133
|
+
.split('-')
|
134
|
+
.map((c) => c.charAt(0).toUpperCase() + c.slice(1))
|
135
|
+
.join('')
|
136
|
+
)
|
137
|
+
: {},
|
138
|
+
};
|
139
|
+
})
|
140
|
+
.filter((f) => f.components.length > 0)
|
141
|
+
: {};
|
142
|
+
fs.writeFile(
|
143
|
+
'./app/javascript/components/components.json',
|
144
|
+
JSON.stringify(components),
|
145
|
+
'utf8',
|
146
|
+
() => {
|
147
|
+
console.log('Component names have been collected.');
|
148
|
+
}
|
149
|
+
);
|
150
|
+
```
|
151
|
+
|
152
|
+
|
153
|
+
## Modules:
|
154
|
+
- Component::Savage
|
155
|
+
Components rendered via method_missing with no extra safety.
|
156
|
+
|
157
|
+
- Component::Sage
|
158
|
+
Components loaded with additional safety. Requires a bit of additional wiring.
|
159
|
+
|
160
|
+
- CML
|
161
|
+
Compose HTML pages with web components. Makes writing a page with Components
|
162
|
+
more similar to writing html.
|
163
|
+
|
164
|
+
- LinkHelper
|
165
|
+
a Rails link_to with webcomponents
|
166
|
+
|
167
|
+
- FormBuilder
|
168
|
+
a Rails form builder using webcomponents
|
169
|
+
|
170
|
+
- IMG
|
171
|
+
A rails image_tag clone
|
172
|
+
|
173
|
+
## Groups
|
174
|
+
- Ragna
|
175
|
+
Load all Asbru in a omakasa way(with sage components).
|
176
|
+
|
177
|
+
- RailsHelpers
|
178
|
+
Load all Asbru Rails helpers
|
179
|
+
|
180
|
+
## Opinions of the author
|
181
|
+
1. Writing Plain old HTML is fun simple and quite universal. Lets make writing
|
182
|
+
components intuitive.
|
183
|
+
2. Less noise makes code more readable.
|
184
|
+
3. Less configuration makes working on projects smoother.
|
185
|
+
|
186
|
+
|
187
|
+
## Design goals
|
188
|
+
If there is such a thing as "The Ivaldi Way" we will stick as close to it as we
|
189
|
+
can.
|
190
|
+
|
191
|
+
## TODO:
|
192
|
+
|
193
|
+
- Make the helpers available using both `Sage` and `Savage`.
|
194
|
+
- Raise an error when incorrect attributes have been supplied to a component.
|
195
|
+
- Add image tag support.
|
196
|
+
- Tie in with rails load cycle.
|
197
|
+
- Run the js script from the gem(on rails startup in production and on ).
|
198
|
+
- Remove the react-rails dependency(or get a better idea about its function).
|
199
|
+
|
200
|
+
## Contributing
|
201
|
+
Contribution directions go here.
|
202
|
+
|
203
|
+
## License
|
204
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Asbru'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
data/lib/asbru.rb
ADDED
data/lib/asbru/cml.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'asbru/components/savage'
|
2
|
+
|
3
|
+
module Asbru
|
4
|
+
# This module defines a bunch of methods that
|
5
|
+
module CML
|
6
|
+
C = Asbru::Components::Savage
|
7
|
+
|
8
|
+
# Problems:
|
9
|
+
# How can we make this module work with Sage/Savage depending on config?
|
10
|
+
# Do we want to do that?
|
11
|
+
|
12
|
+
# Ideas:
|
13
|
+
# 1. We can make Sage implement to exactly the same interface as Savage and
|
14
|
+
# somehow inject it.
|
15
|
+
# 2. We could also ALWAYS load the sage classed needed here and call these
|
16
|
+
# required.
|
17
|
+
#
|
18
|
+
# I think I prefer 1 even though the syntax of Sage is nicer imo.
|
19
|
+
class << self
|
20
|
+
def p text, **opts
|
21
|
+
C.text_content text: text, **opts
|
22
|
+
end
|
23
|
+
|
24
|
+
def h1 text, **opts
|
25
|
+
C.text_title size: 'h1', text: text
|
26
|
+
end
|
27
|
+
|
28
|
+
def h2 text, **opts
|
29
|
+
C.text_title size: 'h2', text: text
|
30
|
+
end
|
31
|
+
|
32
|
+
def h3 text, **opts
|
33
|
+
C.text_title size: 'h3', text: text
|
34
|
+
end
|
35
|
+
|
36
|
+
def h4 text, **opts
|
37
|
+
C.text_title size: 'h4', text: text
|
38
|
+
end
|
39
|
+
|
40
|
+
def h5 text, **opts
|
41
|
+
C.text_title size: 'h5', text: text
|
42
|
+
end
|
43
|
+
|
44
|
+
def hr color: 'stable-500'
|
45
|
+
C.ui_divider color: color, height: 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def vertical_spacer height
|
49
|
+
C.ui_divider color: :transparent, height: height
|
50
|
+
end
|
51
|
+
|
52
|
+
def table_row(*cells)
|
53
|
+
{ data: cells }
|
54
|
+
end
|
55
|
+
|
56
|
+
def table_cell(text, action: nil, method: nil, confirm: nil, color: nil)
|
57
|
+
cell = { text: text}
|
58
|
+
cell[:color] = color if color.present?
|
59
|
+
cell[:action] = action if action.present?
|
60
|
+
cell[:customData] = {}
|
61
|
+
cell[:customData]['data-method'] = method if method.present?
|
62
|
+
cell[:customData]['data-confirm'] = confirm if confirm.present?
|
63
|
+
cell
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Asbru
|
2
|
+
module Components
|
3
|
+
# This module uses components.json to see what components are available to
|
4
|
+
# be rendered. Because it defines methods on runtime instead of relying on
|
5
|
+
# method_missing its quite a bit faster and provides better feedback in
|
6
|
+
# case of errors. This implementation is just a PoC and doesn't work atm.
|
7
|
+
# More on this later!
|
8
|
+
class Sage
|
9
|
+
extend ::React::Rails::ViewHelper
|
10
|
+
class << self
|
11
|
+
def setup
|
12
|
+
file = File.open(Rails.root.join('app',
|
13
|
+
'javascript',
|
14
|
+
'components',
|
15
|
+
'components.json'))
|
16
|
+
|
17
|
+
JSON.parse(file.read).each do |folder|
|
18
|
+
cname = folder['folder'].capitalize
|
19
|
+
const_set cname, Class.new
|
20
|
+
klass = "Asbru::Components::Sage::#{cname}".constantize
|
21
|
+
klass.extend ::React::Rails::ViewHelper
|
22
|
+
|
23
|
+
folder['components'].each do |component_name|
|
24
|
+
method_name = component_name.underscore.to_sym
|
25
|
+
|
26
|
+
klass.define_singleton_method(method_name) do |**opts|
|
27
|
+
react_component "#{folder['folder']}.#{component_name}", **opts
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# We use method missing to enable the make this available via the same
|
34
|
+
# API as Savage. The other API here is nicer and maybe we should create
|
35
|
+
# a way to disable the savage API.
|
36
|
+
def method_missing(method_id, **opts)
|
37
|
+
return super if self.respond_to? :method_id
|
38
|
+
|
39
|
+
name_parts = method_id.to_s.split('_')
|
40
|
+
namespace = name_parts.shift.capitalize
|
41
|
+
|
42
|
+
"Asbru::Components::Sage::#{namespace}".constantize
|
43
|
+
.send(name_parts.join('_'), **opts)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Asbru
|
2
|
+
module Components
|
3
|
+
# This module is used to generate react components in the views and loads
|
4
|
+
# them via method missing without additional checking.
|
5
|
+
# It doesn't offer any benefits over react::rails
|
6
|
+
class Savage
|
7
|
+
extend ::React::Rails::ViewHelper
|
8
|
+
class << self
|
9
|
+
def method_missing(method_id, **opts)
|
10
|
+
if self.respond_to? :method_id
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
name_parts = method_id.to_s.split('_')
|
15
|
+
namespace = name_parts.shift
|
16
|
+
name = name_parts.map(&:capitalize).join('')
|
17
|
+
|
18
|
+
react_component "#{namespace}.#{name}", opts
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'asbru/components/savage'
|
2
|
+
|
3
|
+
module Asbru
|
4
|
+
class FormBuilder < ActionView::Helpers::FormBuilder
|
5
|
+
module Helper
|
6
|
+
def asbru_form(**options, &block)
|
7
|
+
options.reverse_merge!(builder: Asbru::FormBuilder)
|
8
|
+
form_with(**options, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def asbru_form_for(record, **options, &block)
|
12
|
+
options.reverse_merge!(builder: Asbru::FormBuilder)
|
13
|
+
form_for(record, **options, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def asbru_form_with(**options, &block)
|
17
|
+
asbru_form(**options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ivaldi_form_for(record, **options, &block)
|
21
|
+
asbru_form_for(record, **options, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def ivaldi_form_with(**options, &block)
|
25
|
+
asbru_form(**options, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
BASIC_FORM_FIELDS = [
|
30
|
+
{ submit: { text: 'Submit', type: 'submit' } },
|
31
|
+
{ date_field: { type: 'datepicker' } },
|
32
|
+
{ password_field: { type: 'password' } },
|
33
|
+
{ text_area: { type: 'textarea' } },
|
34
|
+
{ email_field: { type: 'email' } },
|
35
|
+
{ check_box: { type: 'checkbox' } },
|
36
|
+
{ file_field: { type: 'file' } },
|
37
|
+
{ text_field: {} },
|
38
|
+
{ telephone_field: { type: 'tel '}}
|
39
|
+
].freeze
|
40
|
+
|
41
|
+
def errors(name)
|
42
|
+
if object.respond_to?(:errors) &&
|
43
|
+
!(name.nil? || object.errors[name].empty?)
|
44
|
+
object.errors.messages.dig(name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def tag_name_for(method, multiple = false)
|
49
|
+
name = ActionView::Helpers::Tags::TextField.new(object_name,
|
50
|
+
method, {})
|
51
|
+
.send(:tag_name)
|
52
|
+
name += '[]' if multiple
|
53
|
+
name
|
54
|
+
end
|
55
|
+
|
56
|
+
def render_form_element(attribute, options)
|
57
|
+
new_options = options.merge(
|
58
|
+
{
|
59
|
+
name: tag_name_for(attribute),
|
60
|
+
errors: errors(attribute)
|
61
|
+
}
|
62
|
+
)
|
63
|
+
|
64
|
+
if @object.present? && attribute.present?
|
65
|
+
if options[:value].nil?
|
66
|
+
# if type of column is date, use default date format
|
67
|
+
if @object.class.try(:columns_hash).present? &&
|
68
|
+
@object.class
|
69
|
+
.columns_hash[attribute.to_s]
|
70
|
+
.try(:type) == :date && @object.send(attribute).present?
|
71
|
+
new_options[:value] = I18n.l(@object.send(attribute),
|
72
|
+
format: I18n.t('date_format.default'))
|
73
|
+
else
|
74
|
+
new_options[:value] = @object.send(attribute)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
if options[:label].nil?
|
78
|
+
new_options[:label] = I18n.t(attribute,
|
79
|
+
scope: "activerecord.attributes.#{@object.class.name.downcase}")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
Asbru::Components::Savage.form_element **new_options
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_options(attribute, choices, chosen)
|
88
|
+
choices.to_h.map do |key, value|
|
89
|
+
{
|
90
|
+
label: key,
|
91
|
+
value: value,
|
92
|
+
name: tag_name_for(attribute),
|
93
|
+
checked: @object.nil? ? false :
|
94
|
+
@object.send(attribute) == chosen
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_collection_options(attribute,
|
100
|
+
collection,
|
101
|
+
value_method,
|
102
|
+
text_method,
|
103
|
+
_options,
|
104
|
+
multiple = false)
|
105
|
+
collection.map do |item|
|
106
|
+
{
|
107
|
+
label: item.send(text_method),
|
108
|
+
value: item.send(value_method),
|
109
|
+
name: tag_name_for(attribute, multiple),
|
110
|
+
checked: if @object.nil?
|
111
|
+
false
|
112
|
+
else
|
113
|
+
if @object.send(attribute).is_a?(Array)
|
114
|
+
@object.send(attribute).include?(item.send(value_method))
|
115
|
+
else
|
116
|
+
@object.send(attribute).to_s == item.send(value_method).to_s
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
BASIC_FORM_FIELDS.each do |item|
|
125
|
+
define_method item.keys.first do |attribute = nil, options = {}|
|
126
|
+
render_form_element(attribute, options.reverse_merge(item.values.first))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def collection_radio_buttons(attribute,
|
131
|
+
collection,
|
132
|
+
value_method,
|
133
|
+
text_method,
|
134
|
+
options = {},
|
135
|
+
html_options = {})
|
136
|
+
render_form_element(attribute, options.merge(html_options).merge(
|
137
|
+
{
|
138
|
+
type: 'radio',
|
139
|
+
options: create_collection_options(attribute,
|
140
|
+
collection,
|
141
|
+
value_method,
|
142
|
+
text_method,
|
143
|
+
options, false)
|
144
|
+
}
|
145
|
+
))
|
146
|
+
end
|
147
|
+
|
148
|
+
def collection_check_boxes(attribute,
|
149
|
+
collection,
|
150
|
+
value_method,
|
151
|
+
text_method,
|
152
|
+
options = {},
|
153
|
+
html_options = {})
|
154
|
+
render_form_element(attribute, options.merge(html_options).merge(
|
155
|
+
{
|
156
|
+
type: 'checkbox',
|
157
|
+
options: create_collection_options(attribute,
|
158
|
+
collection,
|
159
|
+
value_method,
|
160
|
+
text_method,
|
161
|
+
options,
|
162
|
+
true)
|
163
|
+
}
|
164
|
+
))
|
165
|
+
end
|
166
|
+
|
167
|
+
def select(attribute,
|
168
|
+
choices = nil,
|
169
|
+
chosen = nil,
|
170
|
+
options = {},
|
171
|
+
html_options = {})
|
172
|
+
render_form_element(
|
173
|
+
attribute, options.merge(html_options).merge(
|
174
|
+
{
|
175
|
+
type: 'select',
|
176
|
+
options: create_options(attribute, choices, chosen)
|
177
|
+
}
|
178
|
+
)
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
def collection_select(attribute,
|
183
|
+
collection,
|
184
|
+
value_method,
|
185
|
+
text_method,
|
186
|
+
options = {},
|
187
|
+
html_options = {})
|
188
|
+
if options[:without_react].present?
|
189
|
+
super
|
190
|
+
else
|
191
|
+
render_form_element(attribute, options.merge(html_options).merge(
|
192
|
+
{
|
193
|
+
type: 'select',
|
194
|
+
options: create_collection_options(attribute,
|
195
|
+
collection,
|
196
|
+
value_method,
|
197
|
+
text_method,
|
198
|
+
options)
|
199
|
+
}
|
200
|
+
))
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def check_box(attribute, options = {})
|
205
|
+
render_form_element(
|
206
|
+
attribute, { type: 'hidden', value: 'false', label: false }
|
207
|
+
).concat(
|
208
|
+
render_form_element(
|
209
|
+
attribute, options.merge({ type: 'checkbox' })
|
210
|
+
)
|
211
|
+
)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
data/lib/asbru/links.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'asbru/components/savage'
|
2
|
+
|
3
|
+
module Asbru
|
4
|
+
module Links
|
5
|
+
module Helper
|
6
|
+
def asbru_link(text,
|
7
|
+
url,
|
8
|
+
method: nil,
|
9
|
+
link: true,
|
10
|
+
confirm: nil,
|
11
|
+
**options)
|
12
|
+
|
13
|
+
options[:text] = text
|
14
|
+
options[:action] = url
|
15
|
+
options[:link] = link
|
16
|
+
|
17
|
+
options[:customData] = {}
|
18
|
+
options[:customData][:'data-method'] = method if method.present?
|
19
|
+
options[:customData][:'data-confirm'] = confirm if confirm.present?
|
20
|
+
options[:customData].merge(options[:custom_data]) if options[:custom_data]
|
21
|
+
Asbru::Components::Savage.button_button(**options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def asbru_link_to(text, url, **options)
|
25
|
+
asbru_link text, url, **options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/asbru/ragna.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# We need some side effects to happen!
|
2
|
+
require 'asbru/rails_helpers'
|
3
|
+
require 'asbru/components/sage'
|
4
|
+
require 'asbru/cml'
|
5
|
+
|
6
|
+
# We use the C for binding components. We might want to make this configurable
|
7
|
+
# later on
|
8
|
+
::C = Asbru::Components::Sage.tap(&:setup)
|
9
|
+
::CML = Asbru::CML
|
10
|
+
|
11
|
+
module Asbru
|
12
|
+
module Ragna
|
13
|
+
include Asbru::RailsHelpers
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: asbru
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stev-0
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.3
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 6.0.3.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 6.0.3
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 6.0.3.5
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: react-rails
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: Creating component based webpages with short hand syntax.
|
48
|
+
email:
|
49
|
+
- skemp@adflow.io
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- MIT-LICENSE
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- lib/asbru.rb
|
58
|
+
- lib/asbru/cml.rb
|
59
|
+
- lib/asbru/components.rb
|
60
|
+
- lib/asbru/components/sage.rb
|
61
|
+
- lib/asbru/components/savage.rb
|
62
|
+
- lib/asbru/form_builder.rb
|
63
|
+
- lib/asbru/links.rb
|
64
|
+
- lib/asbru/ragna.rb
|
65
|
+
- lib/asbru/rails_helpers.rb
|
66
|
+
- lib/asbru/railtie.rb
|
67
|
+
- lib/asbru/version.rb
|
68
|
+
- lib/asbru/view_helpers.rb
|
69
|
+
- lib/tasks/asbru_tasks.rake
|
70
|
+
homepage: https://rubygems.org/gems/asbru
|
71
|
+
licenses:
|
72
|
+
- MIT
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubygems_version: 3.1.2
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: Asbru is a tool for creating component based webpages.
|
93
|
+
test_files: []
|