smart_navigation 0.1.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 322510ff431e621ac05e9a7114fc15ad656bd6be
4
- data.tar.gz: 4257511a0085900ef8be0f89bb0a7bb105da50b3
3
+ metadata.gz: 032655f9ab35419c26f5b36b2ebb58bc044cee25
4
+ data.tar.gz: 54e5513ff6c6954ce05e6e25bdd205279b421a40
5
5
  SHA512:
6
- metadata.gz: 6fa49d788f5b38b65c19688393888c3b19a991e6eec39048d2bfda5d0382e3c25407cde74aad5b2ba0f7ee5c0d07df37e7de801e17da59711ecbce5f9933e199
7
- data.tar.gz: 68a2d5cdf34287d02cbd335c832d42a5fd05ab09a7d18f5be4386b80f79c518ba0347fba8f80588f4910f4f9e3015280563f3c4245d34a2a136d6bacdd861467
6
+ metadata.gz: 2413436e93175f1ca0eb2771740962d755a5f50d6775db282176b01fa6eced57d5a1aa8e6eee7504ba9b562f0847e852c0cc2b964d13463b9610e627b5c920b9
7
+ data.tar.gz: b23f3b1a58cd012667d80f1835fba875fd06f6e4bc43680c0a2c532989d1b3fd7cfdf2cd003fc91856481fec869698a6c10e53532748f981df84989c0d73c5bd
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SmartNavigation
2
2
 
3
- View helpers for navigation menus. Build navigation menus from hash configs.
3
+ View helpers for navigation menus. Build navigation menus from hash objects.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/smart_navigation.svg)](https://badge.fury.io/rb/smart_navigation)
6
6
  [![Build Status](https://travis-ci.org/hardpixel/smart-navigation.svg?branch=master)](https://travis-ci.org/hardpixel/smart-navigation)
@@ -24,7 +24,70 @@ Or install it yourself as:
24
24
 
25
25
  ## Usage
26
26
 
27
- TODO: Write usage instructions here
27
+ Define the menu items in a hash:
28
+
29
+ ```ruby
30
+ @items = {
31
+ dashboard: {
32
+ label: 'Dashboard',
33
+ url: :root_path,
34
+ icon: 'dashboard'
35
+ },
36
+ pages: {
37
+ label: 'Pages',
38
+ url: :admin_pages_path,
39
+ icon: 'pages',
40
+ children: {
41
+ index: {
42
+ label: 'All Pages',
43
+ url: :pages_path
44
+ },
45
+ new: {
46
+ label: 'New Page',
47
+ url: :new_page_path
48
+ }
49
+ }
50
+ },
51
+ system: {
52
+ label: 'System',
53
+ separator: true
54
+ },
55
+ profile: {
56
+ label: 'Profile',
57
+ url: -> { edit_user_path(current_user) },
58
+ icon: 'user',
59
+ if: :user_signed_in?
60
+ }
61
+ }
62
+ ```
63
+
64
+ The `url` key can be a String, a Symbol or a Proc. Keys `if` and `unless` can be a Symbol or a Proc. Symbols and Procs are executed in the view context.
65
+
66
+ To render a menu you can use the `navigation_for` or `smart_navigation_for` helper in your views:
67
+
68
+ ```erb
69
+ <%= smart_navigation_for(@items) %>
70
+ ```
71
+
72
+ There are a number of options you can use to customize the navigation. The default options are:
73
+
74
+ ```ruby
75
+ options = {
76
+ menu_class: 'menu',
77
+ menu_html: {},
78
+ separator_class: 'separator',
79
+ submenu_parent_class: 'has-submenu',
80
+ submenu_class: 'submenu',
81
+ active_class: 'active',
82
+ active_submenu_class: 'open',
83
+ submenu_icons: false,
84
+ submenu_toggle: nil,
85
+ icon_prefix: 'icon icon-',
86
+ icon_position: 'left'
87
+ }
88
+
89
+ smart_navigation_for(@items, options)
90
+ ```
28
91
 
29
92
  ## Development
30
93
 
@@ -2,107 +2,159 @@ module SmartNavigation
2
2
  class Renderer
3
3
  # Initialize builder
4
4
  def initialize(view_context, items, options={})
5
- @context = view_context
6
- @items = sort_items items
7
- @menu_class = options.fetch :menu_class, 'menu'
8
- @sep_class = options.fetch :separator_class, 'separator'
9
- @group_class = options.fetch :group_class, 'menu-group'
10
- @submenu_class = options.fetch :submenu_class, 'submenu'
11
- @active_class = options.fetch :active_class, 'active'
12
- @active_submenu_class = options.fetch :active_submenu_class, 'open'
13
- @submenu_icons = options.fetch :submenu_icons, false
5
+ @context = view_context
6
+ @items = sort_items items
7
+ @options = default_options.merge(options)
14
8
  end
15
9
 
16
- # Sort items by order
17
- def sort_items(items)
18
- items.sort_by { |_k, v| v[:order] }.to_h
10
+ # Render menu
11
+ def render
12
+ menu_tag @items.map { |k, v| item_tag(v, true) }.join
19
13
  end
20
14
 
21
- # Get menu item url
22
- def item_url(item)
23
- params = { controller: item[:controller], action: item[:action] }
24
- params[:action] ? url_for(params) : "##{item[:id]}"
25
- end
15
+ private
16
+
17
+ # Default options
18
+ def default_options
19
+ {
20
+ menu_class: 'menu',
21
+ menu_html: {},
22
+ separator_class: 'separator',
23
+ submenu_parent_class: 'has-submenu',
24
+ submenu_class: 'submenu',
25
+ active_class: 'active',
26
+ active_submenu_class: 'open',
27
+ submenu_icons: false,
28
+ submenu_toggle: nil,
29
+ icon_prefix: 'icon icon-',
30
+ icon_position: 'left'
31
+ }
32
+ end
26
33
 
27
- # Check if current page
28
- def current_page?(item)
29
- url = item_url(item)
30
- @context.current_page?(url)
31
- end
34
+ # Sort items by order
35
+ def sort_items(items)
36
+ items.sort_by { |_k, v| v[:order] }.to_h
37
+ end
32
38
 
33
- # Check if current group
34
- def current_group?(item)
35
- current = item[:children].any? { |_k, v| current_page?(v) }
36
- current = item[:children].any? { |_k, v| current_group?(v) } if current.blank?
37
- current
38
- end
39
+ # Get menu item url
40
+ def item_url(item)
41
+ item[:url].present? ? mixed_value(item[:url]) : "##{item[:id]}"
42
+ end
39
43
 
40
- # Create menu separator
41
- def separator_tag(item)
42
- content_tag :li, item[:label], class: @sep_class
43
- end
44
+ # Check if should render item
45
+ def render_item?(item)
46
+ if item[:if]
47
+ mixed_value(item[:if]).present?
48
+ elsif item[:unless]
49
+ mixed_value(item[:unless]).blank?
50
+ else
51
+ true
52
+ end
53
+ end
44
54
 
45
- # Create item link
46
- def item_link_tag(item, icons=false)
47
- arrow = content_tag :span, icon('angle-left pull-right'), class: 'pull-right-container'
48
- label = content_tag :span, item[:label]
49
- label = icon("#{item[:icon]}") + label if icons.present?
50
- label = label + arrow if item[:children].present?
55
+ # Check if current page
56
+ def current_page?(item)
57
+ url = item_url(item)
58
+ @context.current_page?(url)
59
+ end
51
60
 
52
- link_to label.html_safe, item_url(item)
53
- end
61
+ # Check if current group
62
+ def current_group?(item)
63
+ current = true if current_page?(item)
64
+ current = Hash(item[:children]).any? { |_k, v| current_page?(v) } if current.blank?
65
+ current = Hash(item[:children]).any? { |_k, v| current_group?(v) } if current.blank?
66
+ current
67
+ end
68
+
69
+ # Create html tag
70
+ def tag(*args, &block)
71
+ @context.content_tag(*args, &block)
72
+ end
54
73
 
55
- # Create submenu item
56
- def submenu_item_tag(item, active=false)
57
- items = sort_items item[:children]
58
- items = items.map { |_k, v| item_tag(v, @submenu_icons) }.join
59
- active = @active_submenu_class if active.present?
74
+ # Create menu icon
75
+ def icon_tag(name, label=nil)
76
+ icon = tag :i, nil, class: "#{@options[:icon_prefix]}#{name}"
60
77
 
61
- content_tag(:ul, items.html_safe, class: "#{active} #{@submenu_class}")
62
- end
78
+ if @options[:icon_position] == 'left'
79
+ "#{icon}#{label}".html_safe
80
+ else
81
+ "#{label}#{icon}".html_safe
82
+ end
83
+ end
63
84
 
64
- # Create group menu item
65
- def group_item_tag(item, icons=false)
66
- active = @active_class if current_group?(item)
67
- link = item_link_tag item, icons
68
- submenu = submenu_item_tag item, active
69
- content = link + submenu
85
+ # Create submenu toggle tag
86
+ def toggle_tag
87
+ "#{@options[:submenu_toggle]}".html_safe
88
+ end
70
89
 
71
- content_tag :li, content.html_safe, class: "#{active} #{@group_class}"
72
- end
90
+ # Create menu separator
91
+ def separator_tag(item)
92
+ tag :li, item[:label], class: @options[:separator_class]
93
+ end
73
94
 
74
- # Create single menu item
75
- def single_item_tag(item, icons=false)
76
- active = @active_class if current_page?(item)
77
- link = item_link_tag(item, icons)
95
+ # Create item link
96
+ def item_link_tag(item, icons=false)
97
+ label = tag :span, item[:label]
98
+ label = icon_tag("#{item[:icon]}", label) if icons.present?
99
+ label = label + toggle_tag if item[:children].present?
78
100
 
79
- content_tag :li, link.html_safe, class: "#{active}"
80
- end
101
+ @context.link_to label.html_safe, item_url(item)
102
+ end
81
103
 
82
- # Create menu list item
83
- def item_tag(item, icons=false)
84
- if item[:separator].present?
85
- separator_tag(item)
86
- elsif item[:children].present?
87
- group_item_tag(item, icons)
88
- else
89
- single_item_tag(item, icons)
104
+ # Create submenu item
105
+ def submenu_item_tag(item, active=false)
106
+ items = sort_items item[:children]
107
+ items = items.map { |_k, v| item_tag(v, @options[:submenu_icons]) }.join
108
+ active = @options[:active_submenu_class] if active.present?
109
+
110
+ tag(:ul, items.html_safe, class: "#{active} #{@options[:submenu_class]}".strip)
90
111
  end
91
- end
92
112
 
93
- # Create menu list
94
- def menu_tag(items)
95
- content_tag :ul, items.html_safe, class: @menu_class
96
- end
113
+ # Create group menu item
114
+ def group_item_tag(item, icons=false)
115
+ active = @options[:active_class] if current_group?(item)
116
+ link = item_link_tag item, icons
117
+ submenu = submenu_item_tag item, active
118
+ content = link + submenu
97
119
 
98
- # Render menu
99
- def render
100
- menu_tag @items.map { |k, v| item_tag(v, true) }.join
101
- end
120
+ tag :li, content.html_safe, class: "#{active} #{@options[:submenu_parent_class]}".strip
121
+ end
102
122
 
103
- # Get app helpers if method is missing
104
- def method_missing(method, *args, &block)
105
- @context.respond_to?(method) ? @context.send(method, *args, &block) : super
106
- end
123
+ # Create single menu item
124
+ def single_item_tag(item, icons=false)
125
+ active = @options[:active_class] if current_page?(item)
126
+ link = item_link_tag(item, icons)
127
+
128
+ tag :li, link.html_safe, class: "#{active}"
129
+ end
130
+
131
+ # Create menu list item
132
+ def item_tag(item, icons=false)
133
+ if render_item?(item)
134
+ if item[:separator].present?
135
+ separator_tag(item)
136
+ elsif item[:children].present?
137
+ group_item_tag(item, icons)
138
+ else
139
+ single_item_tag(item, icons)
140
+ end
141
+ end
142
+ end
143
+
144
+ # Create menu list
145
+ def menu_tag(items)
146
+ tag :ul, items.html_safe, Hash(@options[:menu_html]).merge(class: @options[:menu_class])
147
+ end
148
+
149
+ # Parse mixed value
150
+ def mixed_value(value)
151
+ if value.is_a?(Proc)
152
+ @context.instance_exec(&value)
153
+ elsif value.is_a?(Symbol)
154
+ @context.send(value)
155
+ else
156
+ value
157
+ end
158
+ end
107
159
  end
108
160
  end
@@ -1,3 +1,3 @@
1
1
  module SmartNavigation
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_navigation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonian Guveli
@@ -72,7 +72,7 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '5.0'
75
- description: View helpers for navigation menus. Build navigation menus from hash configs.
75
+ description: View helpers for navigation menus. Build navigation menus from hash objects.
76
76
  email:
77
77
  - jonian@hardpixel.eu
78
78
  executables: []