tramway 0.4.8 → 0.4.9.2
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 +55 -1
- data/app/assets/javascripts/tramway/multiselect_controller.js +131 -0
- data/app/components/tailwinds/form/builder.rb +11 -2
- data/app/components/tailwinds/form/multiselect/dropdown_container.html.haml +3 -0
- data/app/components/tailwinds/form/multiselect/dropdown_container.rb +11 -0
- data/app/components/tailwinds/form/multiselect/item_container.html.haml +5 -0
- data/app/components/tailwinds/form/multiselect/item_container.rb +11 -0
- data/app/components/tailwinds/form/multiselect/select_as_input.html.haml +2 -0
- data/app/components/tailwinds/form/multiselect/select_as_input.rb +16 -0
- data/app/components/tailwinds/form/multiselect/selected_item_template.html.haml +6 -0
- data/app/components/tailwinds/form/multiselect/selected_item_template.rb +11 -0
- data/app/components/tailwinds/form/multiselect_component.html.haml +10 -0
- data/app/components/tailwinds/form/multiselect_component.rb +73 -0
- data/app/components/tailwinds/form/select_component.rb +1 -1
- data/config/routes.rb +2 -0
- data/lib/rules/turbo_html_attributes_rules.rb +1 -1
- data/lib/tramway/configs/entity.rb +15 -8
- data/lib/tramway/engine.rb +4 -0
- data/lib/tramway/helpers/navbar_helper.rb +1 -1
- data/lib/tramway/helpers/views_helper.rb +2 -2
- data/lib/tramway/navbar.rb +7 -7
- data/lib/tramway/utils/render.rb +2 -2
- data/lib/tramway/version.rb +1 -1
- metadata +31 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17ef05a91356ce84f217df49af7245c2df48abd356625f7c99e2d96f693d5fb7
|
4
|
+
data.tar.gz: 002da5b891c4eea585c317b006aface8f1443652ec1700f02078d0a47a920068
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a0c3cb1ce60c537818e0fe62812128f15e8f1dcdf6f523d60b6b93e3413a20e4b9b19f7a1228b18b7a7e253083775a3244c6dfd2a80034d2bbb5e3ebf23e746
|
7
|
+
data.tar.gz: e0cfa260fb65d82fa5e0928ada86e01b1097b213f83fb2b5907e75f6c0e93b9ea196a682be2fb30b5058f1802b53a026a909b33138b6f08019d0918e2981f0d0
|
data/README.md
CHANGED
@@ -8,7 +8,9 @@ Unite Ruby on Rails brilliance. Streamline development with Tramway.
|
|
8
8
|
* [Tramway Form](https://github.com/Purple-Magic/tramway#tramway-form)
|
9
9
|
* [Tramway Navbar](https://github.com/Purple-Magic/tramway#tramway-navbar)
|
10
10
|
* [Tailwind-styled forms](https://github.com/Purple-Magic/tramway#tailwind-styled-forms)
|
11
|
+
* [Stimulus-based inputs](https://github.com/Purple-Magic/tramway#stimulus-based-inputs)
|
11
12
|
* [Tailwind-styled pagination](https://github.com/Purple-Magic/tramway?tab=readme-ov-file#tailwind-styled-pagination-for-kaminari)
|
13
|
+
* [Articles](https://github.com/Purple-Magic/tramway#usage)
|
12
14
|
|
13
15
|
## Installation
|
14
16
|
Add this line to your application's Gemfile:
|
@@ -363,6 +365,17 @@ tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500
|
|
363
365
|
end
|
364
366
|
```
|
365
367
|
|
368
|
+
# Haml example
|
369
|
+
|
370
|
+
```haml
|
371
|
+
= tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500 } do |nav|
|
372
|
+
- nav.left do
|
373
|
+
- nav.item 'Users', '/users'
|
374
|
+
- nav.item 'Podcasts', '/podcasts'
|
375
|
+
- nav.right do
|
376
|
+
- nav.item 'Sign out', '/users/sessions', method: :delete, confirm: 'Wanna quit?'
|
377
|
+
```
|
378
|
+
|
366
379
|
will render [this](https://play.tailwindcss.com/UZPTCudFw5)
|
367
380
|
|
368
381
|
#### tramway_navbar
|
@@ -421,10 +434,11 @@ Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are
|
|
421
434
|
Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by default.
|
422
435
|
|
423
436
|
```ruby
|
424
|
-
= tramway_form_for
|
437
|
+
= tramway_form_for @user do |f|
|
425
438
|
= f.text_field :text
|
426
439
|
= f.password_field :password
|
427
440
|
= f.select :role, [:admin, :user]
|
441
|
+
= f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']]
|
428
442
|
= f.file_field :file
|
429
443
|
= f.submit "Create User"
|
430
444
|
```
|
@@ -436,8 +450,42 @@ Available form helpers:
|
|
436
450
|
* password_field
|
437
451
|
* file_field
|
438
452
|
* select
|
453
|
+
* multiselect ([Stimulus-based](https://github.com/Purple-Magic/tramway#stimulus-based-inputs))
|
439
454
|
* submit
|
440
455
|
|
456
|
+
#### Stimulus-based inputs
|
457
|
+
|
458
|
+
`tramway_form_for` provides Tailwind-styled Stimulus-based custom inputs.
|
459
|
+
|
460
|
+
##### Multiselect
|
461
|
+
|
462
|
+
In case you want to use tailwind-styled multiselect this way
|
463
|
+
|
464
|
+
```haml
|
465
|
+
= tramway_form_for @user do |f|
|
466
|
+
= f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']]
|
467
|
+
#- ...
|
468
|
+
```
|
469
|
+
|
470
|
+
you should add Tramway Multiselect Stimulus controller to your application.
|
471
|
+
|
472
|
+
Example for [importmap-rails](https://github.com/rails/importmap-rails) config
|
473
|
+
|
474
|
+
*config/importmap.rb*
|
475
|
+
```ruby
|
476
|
+
pin '@tramway/multiselect', to: 'tramway/multiselect_controller.js'
|
477
|
+
```
|
478
|
+
|
479
|
+
*app/javascript/controllers/index.js*
|
480
|
+
```js
|
481
|
+
import { application } from "controllers/application"
|
482
|
+
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
|
483
|
+
import { Multiselect } from "@tramway/multiselect" // importing Multiselect controller class
|
484
|
+
eagerLoadControllersFrom("controllers", application)
|
485
|
+
|
486
|
+
application.register('multiselect', Multiselect) // register Multiselect controller class as `multiselect` stimulus controller
|
487
|
+
```
|
488
|
+
|
441
489
|
### Tailwind-styled pagination for Kaminari
|
442
490
|
|
443
491
|
Tramway uses [Tailwind](https://tailwindcss.com/) by default. It has tailwind-styled pagination for [kaminari](https://github.com/kaminari/kaminari).
|
@@ -480,6 +528,12 @@ user_2 = tramway_form User.first
|
|
480
528
|
user_2.object #=> returns pure user object
|
481
529
|
```
|
482
530
|
|
531
|
+
## Articles
|
532
|
+
* [Tramway on Rails](https://kalashnikovisme.medium.com/tramway-on-rails-32158c35ed68)
|
533
|
+
* [Delegating ActiveRecord methods to decorators in Rails](https://kalashnikovisme.medium.com/delegating-activerecord-methods-to-decorators-in-rails-4e4ec1c6b3a6)
|
534
|
+
* [Behave as ActiveRecord. Why do we want objects to be AR lookalikes?](https://kalashnikovisme.medium.com/behave-as-activerecord-why-do-we-want-objects-to-be-ar-lookalikes-d494d692e1d3)
|
535
|
+
* [Decorating associations in Rails with Tramway](https://kalashnikovisme.medium.com/decorating-associations-in-rails-with-tramway-b46a28392f9e)
|
536
|
+
|
483
537
|
## Contributing
|
484
538
|
|
485
539
|
Install [lefthook](https://github.com/evilmartians/lefthook)
|
@@ -0,0 +1,131 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
export default class Multiselect extends Controller {
|
4
|
+
static targets = ["dropdown", "showSelectedArea", "hiddenInput"];
|
5
|
+
|
6
|
+
static values = {
|
7
|
+
items: Array,
|
8
|
+
dropdownContainer: String,
|
9
|
+
itemContainer: String,
|
10
|
+
selectedItemTemplate: String,
|
11
|
+
dropdownState: String,
|
12
|
+
selectedItems: Array,
|
13
|
+
placeholder: String,
|
14
|
+
selectAsInput: String,
|
15
|
+
value: Array
|
16
|
+
}
|
17
|
+
|
18
|
+
connect() {
|
19
|
+
this.dropdownState = 'closed';
|
20
|
+
this.unselectedItems = JSON.parse(this.element.dataset.items).map((item) => {
|
21
|
+
return {
|
22
|
+
text: item.text,
|
23
|
+
value: item.value.toString()
|
24
|
+
}
|
25
|
+
});
|
26
|
+
|
27
|
+
const initialValues = this.element.dataset.value === undefined ? [] : this.element.dataset.value.split(',')
|
28
|
+
this.selectedItems = this.unselectedItems.filter(item => initialValues.includes(item.value));
|
29
|
+
this.unselectedItems = this.unselectedItems.filter(item => !initialValues.includes(item.value));
|
30
|
+
|
31
|
+
this.renderSelectedItems();
|
32
|
+
}
|
33
|
+
|
34
|
+
renderSelectedItems() {
|
35
|
+
const allItems = this.fillTemplate(this.element.dataset.selectedItemTemplate, this.selectedItems);
|
36
|
+
this.showSelectedAreaTarget.innerHTML = allItems;
|
37
|
+
this.showSelectedAreaTarget.insertAdjacentHTML("beforeEnd", this.input());
|
38
|
+
this.updateInputOptions();
|
39
|
+
}
|
40
|
+
|
41
|
+
fillTemplate(template, items) {
|
42
|
+
return items.map((item) => {
|
43
|
+
return template.replace(/{{text}}/g, item.text).replace(/{{value}}/g, item.value)
|
44
|
+
}).join('')
|
45
|
+
}
|
46
|
+
|
47
|
+
closeOnClickOutside(event) {
|
48
|
+
if (this.dropdownState === 'open' && !this.element.contains(event.target)) {
|
49
|
+
this.closeDropdown();
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
toggleDropdown() {
|
54
|
+
if (this.dropdownState === 'closed') {
|
55
|
+
this.openDropdown();
|
56
|
+
} else {
|
57
|
+
this.closeDropdown();
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
rerenderItems() {
|
62
|
+
this.closeDropdown();
|
63
|
+
this.openDropdown();
|
64
|
+
}
|
65
|
+
|
66
|
+
openDropdown() {
|
67
|
+
this.dropdownState = 'open';
|
68
|
+
this.dropdownTarget.insertAdjacentHTML("afterend", this.template);
|
69
|
+
|
70
|
+
if (this.dropdown()) {
|
71
|
+
this.dropdown().addEventListener('click', event => event.stopPropagation());
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
dropdown() {
|
76
|
+
return this.element.querySelector('#dropdown');
|
77
|
+
}
|
78
|
+
|
79
|
+
closeDropdown() {
|
80
|
+
this.dropdownState = 'closed';
|
81
|
+
if (this.dropdown()) {
|
82
|
+
this.dropdown().remove();
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
get template() {
|
87
|
+
return this.element.dataset.dropdownContainer.replace(
|
88
|
+
/{{content}}/g,
|
89
|
+
this.fillTemplate(this.element.dataset.itemContainer, this.unselectedItems)
|
90
|
+
);
|
91
|
+
}
|
92
|
+
|
93
|
+
toggleItem({ currentTarget }) {
|
94
|
+
const item = {
|
95
|
+
text: currentTarget.dataset.text,
|
96
|
+
value: currentTarget.dataset.value
|
97
|
+
};
|
98
|
+
|
99
|
+
const itemIndex = this.selectedItems.findIndex(x => x.value === item.value);
|
100
|
+
if (itemIndex !== -1) {
|
101
|
+
this.selectedItems = this.selectedItems.filter((_, index) => index !== itemIndex);
|
102
|
+
} else {
|
103
|
+
this.selectedItems.push(item);
|
104
|
+
}
|
105
|
+
|
106
|
+
this.unselectedItems = this.unselectedItems.filter(x => x.value !== item.value);
|
107
|
+
|
108
|
+
this.renderSelectedItems();
|
109
|
+
this.rerenderItems();
|
110
|
+
}
|
111
|
+
|
112
|
+
input() {
|
113
|
+
const placeholder = this.selectedItems.length > 0 ? '' : this.element.dataset.placeholder;
|
114
|
+
return this.element.dataset.selectAsInput.replace(/{{placeholder}}/g, placeholder);
|
115
|
+
}
|
116
|
+
|
117
|
+
updateInputOptions() {
|
118
|
+
this.hiddenInputTarget.innerHTML = '';
|
119
|
+
this.selectedItems.forEach(selected => {
|
120
|
+
const option = document.createElement("option");
|
121
|
+
option.text = selected.text;
|
122
|
+
option.value = selected.value;
|
123
|
+
option.setAttribute("selected", true);
|
124
|
+
this.hiddenInputTarget.append(option);
|
125
|
+
});
|
126
|
+
|
127
|
+
this.hiddenInputTarget.value = this.selectedItems.map(item => item.value);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
export { Multiselect }
|
@@ -35,8 +35,17 @@ module Tailwinds
|
|
35
35
|
), &)
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
render(Tailwinds::Form::
|
38
|
+
def multiselect(attribute, collection, **options, &)
|
39
|
+
render(Tailwinds::Form::MultiselectComponent.new(
|
40
|
+
input: input(:text_field),
|
41
|
+
value: options[:value] || options[:selected] || object.public_send(attribute)&.first,
|
42
|
+
collection:,
|
43
|
+
**default_options(attribute, options)
|
44
|
+
), &)
|
45
|
+
end
|
46
|
+
|
47
|
+
def submit(action, **, &)
|
48
|
+
render(Tailwinds::Form::SubmitButtonComponent.new(action, **), &)
|
40
49
|
end
|
41
50
|
|
42
51
|
private
|
@@ -0,0 +1,5 @@
|
|
1
|
+
.cursor-pointer.w-full.border-gray-100.rounded-t.border-b.hover:bg-teal-100{ data: { action: "click->multiselect#toggleItem", text: "{{text}}", value: "{{value}}" } }
|
2
|
+
.flex.w-full.items-center.p-2.pl-2.border-transparent.border-l-2.relative.hover:border-teal-100
|
3
|
+
.w-full.items-center.flex
|
4
|
+
.mx-2.leading-6
|
5
|
+
{{text}}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tailwinds
|
4
|
+
module Form
|
5
|
+
module Multiselect
|
6
|
+
# Renders input as select
|
7
|
+
class SelectAsInput < ViewComponent::Base
|
8
|
+
extend Dry::Initializer[undefined: false]
|
9
|
+
|
10
|
+
option :options
|
11
|
+
option :attribute
|
12
|
+
option :input
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
.flex.justify-center.items-center.m-1.font-medium.py-1.px-2.bg-white.rounded-full.text-teal-700.bg-teal-100.border.border-teal-300
|
2
|
+
.text-xs.font-normal.leading-none.max-w-full.flex-initial
|
3
|
+
{{text}}
|
4
|
+
.flex.flex-auto.flex-row-reverse
|
5
|
+
.cursor-pointer{ data: { action: "click->multiselect#toggleItem", text: "{{text}}", value: "{{value}}" } }
|
6
|
+
⨯
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.mb-4
|
2
|
+
- if @label
|
3
|
+
%label.block.text-gray-700.text-sm.font-bold.mb-2{ for: @for }
|
4
|
+
= @label
|
5
|
+
.flex.flex-col.items-center.relative{ data: multiselect_hash, id: "#{@for}_multiselect" }
|
6
|
+
.min-w-96.w-fit
|
7
|
+
.p-1.flex.border.border-gray-200.bg-white.rounded{ data: { "multiselect-target" => "dropdown" } }
|
8
|
+
.flex.flex-auto.flex-wrap{ data: { "multiselect-target" => "showSelectedArea" } }
|
9
|
+
.text-gray-300.w-8.py-1.pl-2.pr-1.border-l.flex.items-center.border-gray-200
|
10
|
+
^
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tailwinds
|
4
|
+
module Form
|
5
|
+
# Tailwind-styled multi-select field
|
6
|
+
class MultiselectComponent < TailwindComponent
|
7
|
+
option :collection
|
8
|
+
|
9
|
+
def before_render
|
10
|
+
@collection = collection.map do |(text, value)|
|
11
|
+
{ text:, value: }
|
12
|
+
end.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
def multiselect_hash
|
16
|
+
{
|
17
|
+
controller:, selected_item_template:, multiselect_selected_items_value:, dropdown_container:, item_container:,
|
18
|
+
items:, action:, select_as_input:, placeholder:, value:
|
19
|
+
}.transform_keys { |key| key.to_s.gsub('_', '-') }
|
20
|
+
end
|
21
|
+
|
22
|
+
def controller
|
23
|
+
:multiselect
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def action
|
29
|
+
'click->multiselect#toggleDropdown'
|
30
|
+
end
|
31
|
+
|
32
|
+
def items
|
33
|
+
collection
|
34
|
+
end
|
35
|
+
|
36
|
+
def placeholder
|
37
|
+
options[:placeholder]
|
38
|
+
end
|
39
|
+
|
40
|
+
def multiselect_selected_items_value
|
41
|
+
[]
|
42
|
+
end
|
43
|
+
|
44
|
+
def select_as_input
|
45
|
+
render(Tailwinds::Form::Multiselect::SelectAsInput.new(options:, attribute:, input:))
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(method_name, *, &)
|
49
|
+
component = component_name(method_name)
|
50
|
+
|
51
|
+
if method_name.to_s.include?('_') && Object.const_defined?(component)
|
52
|
+
render(component.constantize.new(*, &))
|
53
|
+
else
|
54
|
+
super
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def respond_to_missing?(method_name, include_private = false)
|
59
|
+
if method_name.to_s.include?('_') && Object.const_defined?(component_name(method_name))
|
60
|
+
true
|
61
|
+
else
|
62
|
+
super
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# :reek:UtilityFunction { enabled: false }
|
67
|
+
def component_name(method_name)
|
68
|
+
"Tailwinds::Form::Multiselect::#{method_name.to_s.camelize}"
|
69
|
+
end
|
70
|
+
# :reek:UtilityFunction { enabled: true }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/config/routes.rb
CHANGED
@@ -9,18 +9,25 @@ module Tramway
|
|
9
9
|
attribute :name, Types::Coercible::String
|
10
10
|
attribute? :route, Tramway::Configs::Entities::Route
|
11
11
|
|
12
|
+
# Route Struct contains implemented in Tramway CRUD and helpful routes for the entity
|
13
|
+
RouteStruct = Struct.new(:index)
|
14
|
+
|
15
|
+
# HumanNameStruct contains human names forms for the entity
|
16
|
+
HumanNameStruct = Struct.new(:single, :plural)
|
17
|
+
|
12
18
|
def routes
|
13
|
-
|
19
|
+
RouteStruct.new(Rails.application.routes.url_helpers.public_send(route_helper_method))
|
14
20
|
end
|
15
21
|
|
16
22
|
def human_name
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
single, plural = if model_class.present?
|
24
|
+
model_name = model_class.model_name.human
|
25
|
+
[model_name, model_name.pluralize]
|
26
|
+
else
|
27
|
+
[name.capitalize, name.pluralize.capitalize]
|
28
|
+
end
|
29
|
+
|
30
|
+
HumanNameStruct.new(single, plural)
|
24
31
|
end
|
25
32
|
|
26
33
|
private
|
data/lib/tramway/engine.rb
CHANGED
@@ -4,8 +4,8 @@ module Tramway
|
|
4
4
|
module Helpers
|
5
5
|
# Provides view-oriented helpers for ActionView
|
6
6
|
module ViewsHelper
|
7
|
-
def tramway_form_for(object,
|
8
|
-
form_for(object,
|
7
|
+
def tramway_form_for(object, *, **options, &)
|
8
|
+
form_for(object, *, **options.merge(builder: Tailwinds::Form::Builder), &)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/tramway/navbar.rb
CHANGED
@@ -33,13 +33,13 @@ module Tramway
|
|
33
33
|
reset_filling
|
34
34
|
end
|
35
35
|
|
36
|
-
def item(text_or_url, url = nil,
|
37
|
-
raise 'You cannot provide an argument and a code block at the same time' if provided_url_and_block?(url, &
|
36
|
+
def item(text_or_url, url = nil, **, &)
|
37
|
+
raise 'You cannot provide an argument and a code block at the same time' if provided_url_and_block?(url, &)
|
38
38
|
|
39
39
|
rendered_item = if url.present?
|
40
|
-
render_ignoring_block(text_or_url, url, **
|
40
|
+
render_ignoring_block(text_or_url, url, **)
|
41
41
|
else
|
42
|
-
render_using_block(text_or_url,
|
42
|
+
render_using_block(text_or_url, **, &)
|
43
43
|
end
|
44
44
|
|
45
45
|
@items[@filling] << rendered_item
|
@@ -79,13 +79,13 @@ module Tramway
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
def render_using_block(text_or_url, method: nil, **options, &
|
82
|
+
def render_using_block(text_or_url, method: nil, **options, &)
|
83
83
|
options.merge!(href: text_or_url)
|
84
84
|
|
85
85
|
if method.present? && method.to_sym != :get
|
86
|
-
context.render(Tailwinds::Nav::Item::ButtonComponent.new(method:, **options), &
|
86
|
+
context.render(Tailwinds::Nav::Item::ButtonComponent.new(method:, **options), &)
|
87
87
|
else
|
88
|
-
context.render(Tailwinds::Nav::Item::LinkComponent.new(method:, **options), &
|
88
|
+
context.render(Tailwinds::Nav::Item::LinkComponent.new(method:, **options), &)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
data/lib/tramway/utils/render.rb
CHANGED
@@ -5,8 +5,8 @@ module Tramway
|
|
5
5
|
# Provides helper method render that depends on ActionController::Base.render method
|
6
6
|
#
|
7
7
|
module Render
|
8
|
-
def render(
|
9
|
-
ActionController::Base.render(
|
8
|
+
def render(*, &)
|
9
|
+
ActionController::Base.render(*, &)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/tramway/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tramway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kalashnikovisme
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name: dry-
|
15
|
+
name: dry-initializer
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: dry-struct
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
@@ -40,41 +40,47 @@ dependencies:
|
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name: rails
|
43
|
+
name: haml-rails
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
48
|
+
version: '0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
55
|
+
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
57
|
+
name: rails
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
62
|
+
version: '7'
|
63
|
+
- - "<"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '9'
|
63
66
|
type: :runtime
|
64
67
|
prerelease: false
|
65
68
|
version_requirements: !ruby/object:Gem::Requirement
|
66
69
|
requirements:
|
67
70
|
- - ">="
|
68
71
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
72
|
+
version: '7'
|
73
|
+
- - "<"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '9'
|
70
76
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
77
|
+
name: view_component
|
72
78
|
requirement: !ruby/object:Gem::Requirement
|
73
79
|
requirements:
|
74
80
|
- - ">="
|
75
81
|
- !ruby/object:Gem::Version
|
76
82
|
version: '0'
|
77
|
-
type: :
|
83
|
+
type: :runtime
|
78
84
|
prerelease: false
|
79
85
|
version_requirements: !ruby/object:Gem::Requirement
|
80
86
|
requirements:
|
@@ -91,11 +97,22 @@ files:
|
|
91
97
|
- MIT-LICENSE
|
92
98
|
- README.md
|
93
99
|
- Rakefile
|
100
|
+
- app/assets/javascripts/tramway/multiselect_controller.js
|
94
101
|
- app/components/tailwind_component.html.haml
|
95
102
|
- app/components/tailwind_component.rb
|
96
103
|
- app/components/tailwinds/form/builder.rb
|
97
104
|
- app/components/tailwinds/form/file_field_component.html.haml
|
98
105
|
- app/components/tailwinds/form/file_field_component.rb
|
106
|
+
- app/components/tailwinds/form/multiselect/dropdown_container.html.haml
|
107
|
+
- app/components/tailwinds/form/multiselect/dropdown_container.rb
|
108
|
+
- app/components/tailwinds/form/multiselect/item_container.html.haml
|
109
|
+
- app/components/tailwinds/form/multiselect/item_container.rb
|
110
|
+
- app/components/tailwinds/form/multiselect/select_as_input.html.haml
|
111
|
+
- app/components/tailwinds/form/multiselect/select_as_input.rb
|
112
|
+
- app/components/tailwinds/form/multiselect/selected_item_template.html.haml
|
113
|
+
- app/components/tailwinds/form/multiselect/selected_item_template.rb
|
114
|
+
- app/components/tailwinds/form/multiselect_component.html.haml
|
115
|
+
- app/components/tailwinds/form/multiselect_component.rb
|
99
116
|
- app/components/tailwinds/form/select_component.html.haml
|
100
117
|
- app/components/tailwinds/form/select_component.rb
|
101
118
|
- app/components/tailwinds/form/submit_button_component.html.haml
|