smart_navigation 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: []