tramway 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +52 -1
- data/app/components/tailwind_component.rb +1 -0
- data/app/components/tailwinds/nav/item_component.rb +3 -14
- data/app/components/tailwinds/navbar_component.rb +20 -14
- data/lib/rules/turbo_html_attributes_rules.rb +18 -0
- data/lib/tramway/base_decorator.rb +50 -0
- data/lib/tramway/decorators/class_helper.rb +24 -0
- data/lib/tramway/decorators/collection_decorator.rb +21 -0
- data/lib/tramway/engine.rb +8 -2
- data/lib/tramway/helpers/decorate_helper.rb +15 -0
- data/lib/tramway/helpers/navbar_helper.rb +26 -4
- data/lib/tramway/navbar.rb +33 -13
- data/lib/tramway/version.rb +1 -1
- data/lib/tramway.rb +1 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c88b945e6fe61b58431c5598687538fb9514ec49333e11bfdb4b4027ff755e94
|
4
|
+
data.tar.gz: dde0abe3237e06f5aa5119e8cd28162643301fb534e949082cb930eca4a2b5dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c27968e67c7c6da3047aadb5be9e39c52eb8049d558777674c8633e34cea10f996e0bf7d3dc04d2744fdd509f9e5019d321a730c2292c55336a2a5e32575b14
|
7
|
+
data.tar.gz: a5eab082d14d3c3158745135fdeedc5bf65789b59b6996523c0584e03522ceeeba63529b25b3549ab368123b6712257865e7098dd7641ec87cbb28358089f0ab
|
data/README.md
CHANGED
@@ -13,7 +13,58 @@ gem "view_component"
|
|
13
13
|
|
14
14
|
### Tailwind components
|
15
15
|
|
16
|
-
Tramway
|
16
|
+
Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are implemented with [ViewComponent](https://github.com/viewcomponent/view_component).
|
17
|
+
|
18
|
+
### Decorators
|
19
|
+
|
20
|
+
Tramway provides convenient decorators for your objects. **NOTE:** This is not the decorator pattern in its usual representation.
|
21
|
+
|
22
|
+
*app/controllers/users_controller.rb*
|
23
|
+
```ruby
|
24
|
+
def index
|
25
|
+
# this line of code decorates the users collection with the default UserDecorator
|
26
|
+
@users = tramway_decorate User.all
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
*app/decorators/user_decorator.rb*
|
31
|
+
```ruby
|
32
|
+
class UserDecorator < Tramway::BaseDecorator
|
33
|
+
# delegates attributes to decorated object
|
34
|
+
delegate_attributes :email, :first_name, :last_name
|
35
|
+
|
36
|
+
# you can provide your own methods with access to decorated object attributes with the method `object`
|
37
|
+
def created_at
|
38
|
+
I18n.l object.created_at
|
39
|
+
end
|
40
|
+
|
41
|
+
# you can provide representations with ViewComponent to avoid implementing views with Rails Helpers
|
42
|
+
def posts_table
|
43
|
+
render TableComponent.new(object.posts)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
#### Decorate single object
|
49
|
+
|
50
|
+
You can use the same method to decorate a single object either
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
def show
|
54
|
+
@user = tramway_decorate User.find params[:id]
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
#### Decorate with a specific decorator
|
59
|
+
|
60
|
+
You can implement a specific decorator and ask Tramway to decorate with it
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
def show
|
64
|
+
@user = tramway_decorate User.find(params[:id]), decorator: Users::ShowDecorator
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
17
68
|
|
18
69
|
### Navbar
|
19
70
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rules/turbo_html_attributes_rules'
|
4
|
+
|
3
5
|
module Tailwinds
|
4
6
|
module Nav
|
5
7
|
# Render button styled with Tailwind using button_to or link_to methods
|
@@ -8,20 +10,7 @@ module Tailwinds
|
|
8
10
|
def initialize(**options)
|
9
11
|
@href = options[:href]
|
10
12
|
@style = 'text-white hover:bg-red-300 px-4 py-2 rounded'
|
11
|
-
@options =
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def prepare(options:)
|
17
|
-
options.reduce({}) do |hash, (key, value)|
|
18
|
-
case key
|
19
|
-
when :method, :confirm
|
20
|
-
hash.deep_merge data: { "turbo_#{key}".to_sym => value }
|
21
|
-
else
|
22
|
-
hash.merge key => value
|
23
|
-
end
|
24
|
-
end
|
13
|
+
@options = Rules::TurboHtmlAttributesRules.prepare_turbo_html_attributes(options:)
|
25
14
|
end
|
26
15
|
end
|
27
16
|
end
|
@@ -1,26 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Tailwinds
|
4
|
-
#
|
4
|
+
# Background helper module
|
5
5
|
#
|
6
|
-
|
7
|
-
def initialize(**options)
|
8
|
-
@title = options[:title]
|
9
|
-
@left_items = options[:left_items]
|
10
|
-
@right_items = options[:right_items]
|
11
|
-
@color = background(options)
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
6
|
+
module BackgroundHelper
|
16
7
|
CSS_COLORS = %i[aqua black blue fuchsia gray green lime maroon navy olive orange purple red
|
17
8
|
silver teal white yellow].freeze
|
18
9
|
MIN_INTENSITY = 100
|
19
10
|
MAX_INTENSITY = 950
|
11
|
+
DEFAULT_BACKGROUND_COLOR = :purple
|
12
|
+
DEFAULT_BACKGROUND_INTENSITY = 700
|
20
13
|
|
21
|
-
def background(options)
|
22
|
-
color = options.dig(:background, :color) ||
|
23
|
-
intensity = options.dig(:background, :intensity) ||
|
14
|
+
def self.background(options)
|
15
|
+
color = options.dig(:background, :color) || DEFAULT_BACKGROUND_COLOR
|
16
|
+
intensity = options.dig(:background, :intensity) || DEFAULT_BACKGROUND_INTENSITY
|
24
17
|
|
25
18
|
unless (MIN_INTENSITY..MAX_INTENSITY).cover?(intensity)
|
26
19
|
raise "Navigation Background Color intensity should be between #{MIN_INTENSITY} and #{MAX_INTENSITY}"
|
@@ -33,4 +26,17 @@ module Tailwinds
|
|
33
26
|
end
|
34
27
|
end
|
35
28
|
end
|
29
|
+
|
30
|
+
# Navbar class main class
|
31
|
+
#
|
32
|
+
class NavbarComponent < TailwindComponent
|
33
|
+
include Tailwinds::BackgroundHelper
|
34
|
+
|
35
|
+
def initialize(**options)
|
36
|
+
@title = options[:title]
|
37
|
+
@left_items = options[:left_items]
|
38
|
+
@right_items = options[:right_items]
|
39
|
+
@color = BackgroundHelper.background(options)
|
40
|
+
end
|
41
|
+
end
|
36
42
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rules
|
4
|
+
# Provides rules for turbo html attributes
|
5
|
+
# It allows users to :method and :confirm attributes instead of data-turbo_method and data-turbo_confirm
|
6
|
+
module TurboHtmlAttributesRules
|
7
|
+
def self.prepare_turbo_html_attributes(options:)
|
8
|
+
options.reduce({}) do |hash, (key, value)|
|
9
|
+
case key
|
10
|
+
when :method, :confirm
|
11
|
+
hash.deep_merge data: { "turbo_#{key}".to_sym => value }
|
12
|
+
else
|
13
|
+
hash.merge key => value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tramway/decorators/collection_decorator'
|
4
|
+
|
5
|
+
module Tramway
|
6
|
+
# Provides decorate function for Tramway projects
|
7
|
+
#
|
8
|
+
class BaseDecorator
|
9
|
+
include Tramway::Decorators::CollectionDecorators
|
10
|
+
|
11
|
+
attr_reader :object, :context
|
12
|
+
|
13
|
+
def initialize(object, context)
|
14
|
+
@object = object
|
15
|
+
@context = context
|
16
|
+
end
|
17
|
+
|
18
|
+
def render(*args)
|
19
|
+
context.render(*args, layout: false)
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def decorate(object_or_array, context)
|
24
|
+
if Tramway::Decorators::CollectionDecorators.collection?(object_or_array)
|
25
|
+
Tramway::Decorators::CollectionDecorators.decorate_collection(collection: object_or_array, context:)
|
26
|
+
else
|
27
|
+
new(object_or_array, context)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def delegate_attributes(*args)
|
32
|
+
args.each do |attribute|
|
33
|
+
delegate attribute, to: :object
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
delegate_attributes :id
|
39
|
+
|
40
|
+
def to_partial_path
|
41
|
+
underscored_class_name = object.class.name.underscore
|
42
|
+
|
43
|
+
"#{underscored_class_name.pluralize}/#{underscored_class_name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_param
|
47
|
+
id.to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway
|
4
|
+
module Decorators
|
5
|
+
# Provides method to determine decorators classes
|
6
|
+
module ClassHelper
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def decorator_class(object_or_array, decorator)
|
10
|
+
if decorator.present?
|
11
|
+
decorator
|
12
|
+
else
|
13
|
+
klass = if Tramway::Decorators::CollectionDecorators.collection?(object_or_array)
|
14
|
+
object_or_array.first.class
|
15
|
+
else
|
16
|
+
object_or_array.class
|
17
|
+
end
|
18
|
+
|
19
|
+
"#{klass}Decorator".constantize
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway
|
4
|
+
module Decorators
|
5
|
+
# Provides functions for collection decorating
|
6
|
+
#
|
7
|
+
module CollectionDecorators
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def decorate_collection(collection:, context:)
|
11
|
+
collection.map do |item|
|
12
|
+
Tramway::Decorators::BaseDecorator.decorate item, context
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def collection?(object)
|
17
|
+
object.class.name.in? ['ActiveRecord::Relation', 'Array']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/tramway/engine.rb
CHANGED
@@ -7,10 +7,16 @@ module Tramway
|
|
7
7
|
isolate_namespace Tramway
|
8
8
|
|
9
9
|
initializer 'tramway.load_helpers' do
|
10
|
-
ActiveSupport.on_load(:action_view) do
|
10
|
+
ActiveSupport.on_load(:action_view) do |loaded_class|
|
11
11
|
require 'tramway/helpers/navbar_helper'
|
12
12
|
|
13
|
-
|
13
|
+
loaded_class.include Tramway::Helpers::NavbarHelper
|
14
|
+
end
|
15
|
+
|
16
|
+
ActiveSupport.on_load(:action_controller) do |loaded_class|
|
17
|
+
require 'tramway/helpers/decorate_helper'
|
18
|
+
|
19
|
+
loaded_class.include Tramway::Helpers::DecorateHelper
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tramway/decorators/class_helper'
|
4
|
+
|
5
|
+
module Tramway
|
6
|
+
module Helpers
|
7
|
+
# Provides methods into Rails ActionController
|
8
|
+
#
|
9
|
+
module DecorateHelper
|
10
|
+
def tramway_decorate(object_or_array, decorator: nil)
|
11
|
+
Tramway::Decorators::ClassHelper.decorator_class(object_or_array, decorator).decorate object_or_array, self
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -5,18 +5,40 @@ require 'tramway/navbar'
|
|
5
5
|
module Tramway
|
6
6
|
module Helpers
|
7
7
|
# Providing navbar helpers for ActionView
|
8
|
-
#
|
9
8
|
module NavbarHelper
|
10
9
|
def tramway_navbar(**options)
|
11
10
|
if block_given?
|
12
|
-
|
11
|
+
initialize_navbar
|
13
12
|
|
14
13
|
yield @navbar
|
15
14
|
|
16
|
-
options
|
17
|
-
options[:right_items] = @navbar.items[:right]
|
15
|
+
assign_navbar_items(options)
|
18
16
|
end
|
19
17
|
|
18
|
+
render_navbar_component(options)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def initialize_navbar
|
24
|
+
@navbar = Tramway::Navbar.new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def assign_navbar_items(options)
|
28
|
+
navbar_items = @navbar.items
|
29
|
+
navbar_items.each do |(key, value)|
|
30
|
+
key_to_merge = case key
|
31
|
+
when :left, :right
|
32
|
+
"#{key}_items".to_sym
|
33
|
+
else
|
34
|
+
key
|
35
|
+
end
|
36
|
+
|
37
|
+
options.merge! key_to_merge => value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def render_navbar_component(options)
|
20
42
|
render(Tailwinds::NavbarComponent.new(**options))
|
21
43
|
end
|
22
44
|
end
|
data/lib/tramway/navbar.rb
CHANGED
@@ -1,48 +1,68 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Tramway
|
4
|
-
# Navbar
|
5
|
-
#
|
4
|
+
# Navbar object provides left and right elements
|
6
5
|
class Navbar
|
7
6
|
attr_reader :items
|
8
7
|
|
9
8
|
def initialize(context)
|
10
9
|
@items = {}
|
11
10
|
@context = context
|
11
|
+
@filling = nil
|
12
12
|
end
|
13
13
|
|
14
14
|
def left
|
15
15
|
return unless block_given?
|
16
16
|
|
17
17
|
@items[:left] = []
|
18
|
-
|
19
|
-
@filling = :left
|
20
|
-
|
18
|
+
filling_side(:left)
|
21
19
|
yield self
|
20
|
+
reset_filling
|
22
21
|
end
|
23
22
|
|
24
23
|
def right
|
25
24
|
return unless block_given?
|
26
25
|
|
27
26
|
@items[:right] = []
|
28
|
-
|
29
|
-
@filling = :right
|
30
|
-
|
27
|
+
filling_side(:right)
|
31
28
|
yield self
|
29
|
+
reset_filling
|
32
30
|
end
|
33
31
|
|
34
32
|
def item(text_or_url, url = nil, **options, &block)
|
35
|
-
raise 'You
|
33
|
+
raise 'You cannot provide an argument and a code block at the same time' if provided_url_and_block?(url, &block)
|
36
34
|
|
37
35
|
rendered_item = if url.present?
|
38
|
-
|
39
|
-
@context.render(Tailwinds::Nav::ItemComponent.new(**options)) { text_or_url }
|
36
|
+
render_ignoring_block(text_or_url, url, options)
|
40
37
|
else
|
41
|
-
options
|
42
|
-
@context.render(Tailwinds::Nav::ItemComponent.new(**options), &block)
|
38
|
+
render_using_block(text_or_url, options, &block)
|
43
39
|
end
|
44
40
|
|
45
41
|
@items[@filling] << rendered_item
|
46
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def provided_url_and_block?(url)
|
47
|
+
url.present? && block_given?
|
48
|
+
end
|
49
|
+
|
50
|
+
def filling_side(side)
|
51
|
+
@filling = side
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset_filling
|
55
|
+
@filling = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def render_ignoring_block(text_or_url, url, options)
|
59
|
+
options.merge!(href: url)
|
60
|
+
@context.render(Tailwinds::Nav::ItemComponent.new(**options)) { text_or_url }
|
61
|
+
end
|
62
|
+
|
63
|
+
def render_using_block(text_or_url, options, &block)
|
64
|
+
options.merge!(href: text_or_url)
|
65
|
+
@context.render(Tailwinds::Nav::ItemComponent.new(**options), &block)
|
66
|
+
end
|
47
67
|
end
|
48
68
|
end
|
data/lib/tramway/version.rb
CHANGED
data/lib/tramway.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
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kalashnikovisme
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-06-
|
12
|
+
date: 2023-06-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: haml-rails
|
@@ -84,9 +84,14 @@ files:
|
|
84
84
|
- app/components/tailwinds/navbar_component.html.haml
|
85
85
|
- app/components/tailwinds/navbar_component.rb
|
86
86
|
- config/routes.rb
|
87
|
+
- lib/rules/turbo_html_attributes_rules.rb
|
87
88
|
- lib/tasks/tramway_tasks.rake
|
88
89
|
- lib/tramway.rb
|
90
|
+
- lib/tramway/base_decorator.rb
|
91
|
+
- lib/tramway/decorators/class_helper.rb
|
92
|
+
- lib/tramway/decorators/collection_decorator.rb
|
89
93
|
- lib/tramway/engine.rb
|
94
|
+
- lib/tramway/helpers/decorate_helper.rb
|
90
95
|
- lib/tramway/helpers/navbar_helper.rb
|
91
96
|
- lib/tramway/navbar.rb
|
92
97
|
- lib/tramway/version.rb
|