tramway 0.1.6 → 0.2.0
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 +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
|