phlexi-menu 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,202 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ phlexi-menu (0.0.1)
5
+ phlex (~> 1.11)
6
+ phlexi-field
7
+ zeitwerk
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionpack (7.2.2)
13
+ actionview (= 7.2.2)
14
+ activesupport (= 7.2.2)
15
+ nokogiri (>= 1.8.5)
16
+ racc
17
+ rack (>= 2.2.4, < 3.2)
18
+ rack-session (>= 1.0.1)
19
+ rack-test (>= 0.6.3)
20
+ rails-dom-testing (~> 2.2)
21
+ rails-html-sanitizer (~> 1.6)
22
+ useragent (~> 0.16)
23
+ actionview (7.2.2)
24
+ activesupport (= 7.2.2)
25
+ builder (~> 3.1)
26
+ erubi (~> 1.11)
27
+ rails-dom-testing (~> 2.2)
28
+ rails-html-sanitizer (~> 1.6)
29
+ activesupport (7.2.2)
30
+ base64
31
+ benchmark (>= 0.3)
32
+ bigdecimal
33
+ concurrent-ruby (~> 1.0, >= 1.3.1)
34
+ connection_pool (>= 2.2.5)
35
+ drb
36
+ i18n (>= 1.6, < 2)
37
+ logger (>= 1.4.2)
38
+ minitest (>= 5.1)
39
+ securerandom (>= 0.3)
40
+ tzinfo (~> 2.0, >= 2.0.5)
41
+ addressable (2.8.7)
42
+ public_suffix (>= 2.0.2, < 7.0)
43
+ ansi (1.5.0)
44
+ appraisal (2.5.0)
45
+ bundler
46
+ rake
47
+ thor (>= 0.14.0)
48
+ ast (2.4.2)
49
+ base64 (0.2.0)
50
+ benchmark (0.3.0)
51
+ bigdecimal (3.1.8)
52
+ builder (3.3.0)
53
+ bundle-audit (0.1.0)
54
+ bundler-audit
55
+ bundler-audit (0.9.2)
56
+ bundler (>= 1.2.0, < 3)
57
+ thor (~> 1.0)
58
+ capybara (3.40.0)
59
+ addressable
60
+ matrix
61
+ mini_mime (>= 0.1.3)
62
+ nokogiri (~> 1.11)
63
+ rack (>= 1.6.0)
64
+ rack-test (>= 0.6.3)
65
+ regexp_parser (>= 1.5, < 3.0)
66
+ xpath (~> 3.2)
67
+ combustion (1.5.0)
68
+ activesupport (>= 3.0.0)
69
+ railties (>= 3.0.0)
70
+ thor (>= 0.14.6)
71
+ concurrent-ruby (1.3.4)
72
+ connection_pool (2.4.1)
73
+ crass (1.0.6)
74
+ drb (2.2.1)
75
+ erubi (1.13.0)
76
+ fiber-local (1.1.0)
77
+ fiber-storage
78
+ fiber-storage (1.0.0)
79
+ i18n (1.14.6)
80
+ concurrent-ruby (~> 1.0)
81
+ io-console (0.7.2)
82
+ irb (1.14.1)
83
+ rdoc (>= 4.0.0)
84
+ reline (>= 0.4.2)
85
+ json (2.7.6)
86
+ language_server-protocol (3.17.0.3)
87
+ lint_roller (1.1.0)
88
+ logger (1.6.1)
89
+ loofah (2.23.1)
90
+ crass (~> 1.0.2)
91
+ nokogiri (>= 1.12.0)
92
+ matrix (0.4.2)
93
+ mini_mime (1.1.5)
94
+ minitest (5.25.1)
95
+ minitest-reporters (1.7.1)
96
+ ansi
97
+ builder
98
+ minitest (>= 5.0)
99
+ ruby-progressbar
100
+ nokogiri (1.16.7-arm64-darwin)
101
+ racc (~> 1.4)
102
+ parallel (1.26.3)
103
+ parser (3.3.6.0)
104
+ ast (~> 2.4.1)
105
+ racc
106
+ phlex (1.11.0)
107
+ phlex-testing-capybara (0.1.0)
108
+ capybara (~> 3.38)
109
+ phlex (>= 0.5)
110
+ phlexi-field (0.0.11)
111
+ activesupport
112
+ fiber-local
113
+ phlex (~> 1.11)
114
+ zeitwerk
115
+ psych (5.2.0)
116
+ stringio
117
+ public_suffix (6.0.1)
118
+ racc (1.8.1)
119
+ rack (3.1.8)
120
+ rack-session (2.0.0)
121
+ rack (>= 3.0.0)
122
+ rack-test (2.1.0)
123
+ rack (>= 1.3)
124
+ rackup (2.2.0)
125
+ rack (>= 3)
126
+ rails-dom-testing (2.2.0)
127
+ activesupport (>= 5.0.0)
128
+ minitest
129
+ nokogiri (>= 1.6)
130
+ rails-html-sanitizer (1.6.0)
131
+ loofah (~> 2.21)
132
+ nokogiri (~> 1.14)
133
+ railties (7.2.2)
134
+ actionpack (= 7.2.2)
135
+ activesupport (= 7.2.2)
136
+ irb (~> 1.13)
137
+ rackup (>= 1.0.0)
138
+ rake (>= 12.2)
139
+ thor (~> 1.0, >= 1.2.2)
140
+ zeitwerk (~> 2.6)
141
+ rainbow (3.1.1)
142
+ rake (13.2.1)
143
+ rdoc (6.7.0)
144
+ psych (>= 4.0.0)
145
+ regexp_parser (2.9.2)
146
+ reline (0.5.11)
147
+ io-console (~> 0.5)
148
+ rubocop (1.66.1)
149
+ json (~> 2.3)
150
+ language_server-protocol (>= 3.17.0)
151
+ parallel (~> 1.10)
152
+ parser (>= 3.3.0.2)
153
+ rainbow (>= 2.2.2, < 4.0)
154
+ regexp_parser (>= 2.4, < 3.0)
155
+ rubocop-ast (>= 1.32.2, < 2.0)
156
+ ruby-progressbar (~> 1.7)
157
+ unicode-display_width (>= 2.4.0, < 3.0)
158
+ rubocop-ast (1.34.0)
159
+ parser (>= 3.3.1.0)
160
+ rubocop-performance (1.22.1)
161
+ rubocop (>= 1.48.1, < 2.0)
162
+ rubocop-ast (>= 1.31.1, < 2.0)
163
+ ruby-progressbar (1.13.0)
164
+ securerandom (0.3.1)
165
+ standard (1.41.1)
166
+ language_server-protocol (~> 3.17.0.2)
167
+ lint_roller (~> 1.0)
168
+ rubocop (~> 1.66.0)
169
+ standard-custom (~> 1.0.0)
170
+ standard-performance (~> 1.5)
171
+ standard-custom (1.0.2)
172
+ lint_roller (~> 1.0)
173
+ rubocop (~> 1.50)
174
+ standard-performance (1.5.0)
175
+ lint_roller (~> 1.1)
176
+ rubocop-performance (~> 1.22.0)
177
+ stringio (3.1.2)
178
+ thor (1.3.2)
179
+ tzinfo (2.0.6)
180
+ concurrent-ruby (~> 1.0)
181
+ unicode-display_width (2.6.0)
182
+ useragent (0.16.10)
183
+ xpath (3.2.0)
184
+ nokogiri (~> 1.8)
185
+ zeitwerk (2.7.1)
186
+
187
+ PLATFORMS
188
+ arm64-darwin
189
+
190
+ DEPENDENCIES
191
+ appraisal
192
+ bundle-audit
193
+ combustion
194
+ minitest
195
+ minitest-reporters
196
+ phlex-testing-capybara
197
+ phlexi-menu!
198
+ rake
199
+ standard
200
+
201
+ BUNDLED WITH
202
+ 2.5.16
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 7.1.3", ">= 7.1.3.4"
6
+ gem "sqlite3", "~> 1.4"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,284 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ phlexi-menu (0.0.1)
5
+ phlex (~> 1.11)
6
+ phlexi-field
7
+ zeitwerk
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actioncable (7.1.3.4)
13
+ actionpack (= 7.1.3.4)
14
+ activesupport (= 7.1.3.4)
15
+ nio4r (~> 2.0)
16
+ websocket-driver (>= 0.6.1)
17
+ zeitwerk (~> 2.6)
18
+ actionmailbox (7.1.3.4)
19
+ actionpack (= 7.1.3.4)
20
+ activejob (= 7.1.3.4)
21
+ activerecord (= 7.1.3.4)
22
+ activestorage (= 7.1.3.4)
23
+ activesupport (= 7.1.3.4)
24
+ mail (>= 2.7.1)
25
+ net-imap
26
+ net-pop
27
+ net-smtp
28
+ actionmailer (7.1.3.4)
29
+ actionpack (= 7.1.3.4)
30
+ actionview (= 7.1.3.4)
31
+ activejob (= 7.1.3.4)
32
+ activesupport (= 7.1.3.4)
33
+ mail (~> 2.5, >= 2.5.4)
34
+ net-imap
35
+ net-pop
36
+ net-smtp
37
+ rails-dom-testing (~> 2.2)
38
+ actionpack (7.1.3.4)
39
+ actionview (= 7.1.3.4)
40
+ activesupport (= 7.1.3.4)
41
+ nokogiri (>= 1.8.5)
42
+ racc
43
+ rack (>= 2.2.4)
44
+ rack-session (>= 1.0.1)
45
+ rack-test (>= 0.6.3)
46
+ rails-dom-testing (~> 2.2)
47
+ rails-html-sanitizer (~> 1.6)
48
+ actiontext (7.1.3.4)
49
+ actionpack (= 7.1.3.4)
50
+ activerecord (= 7.1.3.4)
51
+ activestorage (= 7.1.3.4)
52
+ activesupport (= 7.1.3.4)
53
+ globalid (>= 0.6.0)
54
+ nokogiri (>= 1.8.5)
55
+ actionview (7.1.3.4)
56
+ activesupport (= 7.1.3.4)
57
+ builder (~> 3.1)
58
+ erubi (~> 1.11)
59
+ rails-dom-testing (~> 2.2)
60
+ rails-html-sanitizer (~> 1.6)
61
+ activejob (7.1.3.4)
62
+ activesupport (= 7.1.3.4)
63
+ globalid (>= 0.3.6)
64
+ activemodel (7.1.3.4)
65
+ activesupport (= 7.1.3.4)
66
+ activerecord (7.1.3.4)
67
+ activemodel (= 7.1.3.4)
68
+ activesupport (= 7.1.3.4)
69
+ timeout (>= 0.4.0)
70
+ activestorage (7.1.3.4)
71
+ actionpack (= 7.1.3.4)
72
+ activejob (= 7.1.3.4)
73
+ activerecord (= 7.1.3.4)
74
+ activesupport (= 7.1.3.4)
75
+ marcel (~> 1.0)
76
+ activesupport (7.1.3.4)
77
+ base64
78
+ bigdecimal
79
+ concurrent-ruby (~> 1.0, >= 1.0.2)
80
+ connection_pool (>= 2.2.5)
81
+ drb
82
+ i18n (>= 1.6, < 2)
83
+ minitest (>= 5.1)
84
+ mutex_m
85
+ tzinfo (~> 2.0)
86
+ addressable (2.8.7)
87
+ public_suffix (>= 2.0.2, < 7.0)
88
+ ansi (1.5.0)
89
+ appraisal (2.5.0)
90
+ bundler
91
+ rake
92
+ thor (>= 0.14.0)
93
+ ast (2.4.2)
94
+ base64 (0.2.0)
95
+ bigdecimal (3.1.8)
96
+ builder (3.3.0)
97
+ bundle-audit (0.1.0)
98
+ bundler-audit
99
+ bundler-audit (0.9.2)
100
+ bundler (>= 1.2.0, < 3)
101
+ thor (~> 1.0)
102
+ capybara (3.40.0)
103
+ addressable
104
+ matrix
105
+ mini_mime (>= 0.1.3)
106
+ nokogiri (~> 1.11)
107
+ rack (>= 1.6.0)
108
+ rack-test (>= 0.6.3)
109
+ regexp_parser (>= 1.5, < 3.0)
110
+ xpath (~> 3.2)
111
+ combustion (1.5.0)
112
+ activesupport (>= 3.0.0)
113
+ railties (>= 3.0.0)
114
+ thor (>= 0.14.6)
115
+ concurrent-ruby (1.3.4)
116
+ connection_pool (2.4.1)
117
+ crass (1.0.6)
118
+ date (3.3.4)
119
+ drb (2.2.1)
120
+ erubi (1.13.0)
121
+ fiber-local (1.1.0)
122
+ fiber-storage
123
+ fiber-storage (1.0.0)
124
+ globalid (1.2.1)
125
+ activesupport (>= 6.1)
126
+ i18n (1.14.6)
127
+ concurrent-ruby (~> 1.0)
128
+ io-console (0.7.2)
129
+ irb (1.14.1)
130
+ rdoc (>= 4.0.0)
131
+ reline (>= 0.4.2)
132
+ json (2.7.6)
133
+ language_server-protocol (3.17.0.3)
134
+ lint_roller (1.1.0)
135
+ loofah (2.23.1)
136
+ crass (~> 1.0.2)
137
+ nokogiri (>= 1.12.0)
138
+ mail (2.8.1)
139
+ mini_mime (>= 0.1.1)
140
+ net-imap
141
+ net-pop
142
+ net-smtp
143
+ marcel (1.0.4)
144
+ matrix (0.4.2)
145
+ mini_mime (1.1.5)
146
+ minitest (5.25.1)
147
+ minitest-reporters (1.7.1)
148
+ ansi
149
+ builder
150
+ minitest (>= 5.0)
151
+ ruby-progressbar
152
+ mutex_m (0.2.0)
153
+ net-imap (0.5.0)
154
+ date
155
+ net-protocol
156
+ net-pop (0.1.2)
157
+ net-protocol
158
+ net-protocol (0.2.2)
159
+ timeout
160
+ net-smtp (0.5.0)
161
+ net-protocol
162
+ nio4r (2.7.3)
163
+ nokogiri (1.16.7-arm64-darwin)
164
+ racc (~> 1.4)
165
+ parallel (1.26.3)
166
+ parser (3.3.6.0)
167
+ ast (~> 2.4.1)
168
+ racc
169
+ phlex (1.11.0)
170
+ phlex-testing-capybara (0.1.0)
171
+ capybara (~> 3.38)
172
+ phlex (>= 0.5)
173
+ phlexi-field (0.0.11)
174
+ activesupport
175
+ fiber-local
176
+ phlex (~> 1.11)
177
+ zeitwerk
178
+ psych (5.2.0)
179
+ stringio
180
+ public_suffix (6.0.1)
181
+ racc (1.8.1)
182
+ rack (3.1.8)
183
+ rack-session (2.0.0)
184
+ rack (>= 3.0.0)
185
+ rack-test (2.1.0)
186
+ rack (>= 1.3)
187
+ rackup (2.2.0)
188
+ rack (>= 3)
189
+ rails (7.1.3.4)
190
+ actioncable (= 7.1.3.4)
191
+ actionmailbox (= 7.1.3.4)
192
+ actionmailer (= 7.1.3.4)
193
+ actionpack (= 7.1.3.4)
194
+ actiontext (= 7.1.3.4)
195
+ actionview (= 7.1.3.4)
196
+ activejob (= 7.1.3.4)
197
+ activemodel (= 7.1.3.4)
198
+ activerecord (= 7.1.3.4)
199
+ activestorage (= 7.1.3.4)
200
+ activesupport (= 7.1.3.4)
201
+ bundler (>= 1.15.0)
202
+ railties (= 7.1.3.4)
203
+ rails-dom-testing (2.2.0)
204
+ activesupport (>= 5.0.0)
205
+ minitest
206
+ nokogiri (>= 1.6)
207
+ rails-html-sanitizer (1.6.0)
208
+ loofah (~> 2.21)
209
+ nokogiri (~> 1.14)
210
+ railties (7.1.3.4)
211
+ actionpack (= 7.1.3.4)
212
+ activesupport (= 7.1.3.4)
213
+ irb
214
+ rackup (>= 1.0.0)
215
+ rake (>= 12.2)
216
+ thor (~> 1.0, >= 1.2.2)
217
+ zeitwerk (~> 2.6)
218
+ rainbow (3.1.1)
219
+ rake (13.2.1)
220
+ rdoc (6.7.0)
221
+ psych (>= 4.0.0)
222
+ regexp_parser (2.9.2)
223
+ reline (0.5.11)
224
+ io-console (~> 0.5)
225
+ rubocop (1.66.1)
226
+ json (~> 2.3)
227
+ language_server-protocol (>= 3.17.0)
228
+ parallel (~> 1.10)
229
+ parser (>= 3.3.0.2)
230
+ rainbow (>= 2.2.2, < 4.0)
231
+ regexp_parser (>= 2.4, < 3.0)
232
+ rubocop-ast (>= 1.32.2, < 2.0)
233
+ ruby-progressbar (~> 1.7)
234
+ unicode-display_width (>= 2.4.0, < 3.0)
235
+ rubocop-ast (1.34.0)
236
+ parser (>= 3.3.1.0)
237
+ rubocop-performance (1.22.1)
238
+ rubocop (>= 1.48.1, < 2.0)
239
+ rubocop-ast (>= 1.31.1, < 2.0)
240
+ ruby-progressbar (1.13.0)
241
+ sqlite3 (1.7.3-arm64-darwin)
242
+ standard (1.41.1)
243
+ language_server-protocol (~> 3.17.0.2)
244
+ lint_roller (~> 1.0)
245
+ rubocop (~> 1.66.0)
246
+ standard-custom (~> 1.0.0)
247
+ standard-performance (~> 1.5)
248
+ standard-custom (1.0.2)
249
+ lint_roller (~> 1.0)
250
+ rubocop (~> 1.50)
251
+ standard-performance (1.5.0)
252
+ lint_roller (~> 1.1)
253
+ rubocop-performance (~> 1.22.0)
254
+ stringio (3.1.2)
255
+ thor (1.3.2)
256
+ timeout (0.4.1)
257
+ tzinfo (2.0.6)
258
+ concurrent-ruby (~> 1.0)
259
+ unicode-display_width (2.6.0)
260
+ websocket-driver (0.7.6)
261
+ websocket-extensions (>= 0.1.0)
262
+ websocket-extensions (0.1.5)
263
+ xpath (3.2.0)
264
+ nokogiri (~> 1.8)
265
+ zeitwerk (2.7.1)
266
+
267
+ PLATFORMS
268
+ arm64-darwin
269
+
270
+ DEPENDENCIES
271
+ appraisal
272
+ bundle-audit
273
+ combustion
274
+ minitest
275
+ minitest-reporters
276
+ phlex-testing-capybara
277
+ phlexi-menu!
278
+ rails (~> 7.1.3, >= 7.1.3.4)
279
+ rake
280
+ sqlite3 (~> 1.4)
281
+ standard
282
+
283
+ BUNDLED WITH
284
+ 2.5.16
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Menu
5
+ class Builder
6
+ attr_reader :items
7
+
8
+ class Item < Phlexi::Menu::Item; end
9
+
10
+ def initialize(&)
11
+ @items = []
12
+
13
+ yield self if block_given?
14
+ end
15
+
16
+ def item(label, **, &)
17
+ new_item = self.class::Item.new(label, **, &)
18
+ @items << new_item
19
+ new_item
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "phlex"
4
+
5
+ module Phlexi
6
+ module Menu
7
+ # Base menu component that other menu renderers can inherit from
8
+ class Component < COMPONENT_BASE
9
+ class Theme < Phlexi::Menu::Theme; end
10
+
11
+ DEFAULT_MAX_DEPTH = 3
12
+
13
+ def initialize(menu, max_depth: DEFAULT_MAX_DEPTH, **options)
14
+ @menu = menu
15
+ @max_depth = max_depth
16
+ @options = options
17
+ super()
18
+ end
19
+
20
+ def view_template
21
+ nav(class: themed(:nav)) do
22
+ render_items(@menu.items)
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ # Base implementation handles nesting and delegates individual item rendering
29
+ def render_items(items, depth = 0)
30
+ return if depth >= @max_depth
31
+ return if items.empty?
32
+
33
+ ul(class: themed(:items_container)) do
34
+ items.each do |item|
35
+ render_item_wrapper(item, depth)
36
+ end
37
+ end
38
+ end
39
+
40
+ def render_item_wrapper(item, depth)
41
+ li(class: tokens(
42
+ themed(:item_wrapper),
43
+ active_class(item),
44
+ item_parent_class(item)
45
+ )) do
46
+ render_item_content(item)
47
+ render_items(item.items, depth + 1) if item.items.any?
48
+ end
49
+ end
50
+
51
+ def render_item_content(item)
52
+ if item.url
53
+ render_item_link(item)
54
+ else
55
+ render_item_span(item)
56
+ end
57
+ end
58
+
59
+ def render_item_link(item)
60
+ a(href: item.url, class: themed(:item_link)) do
61
+ render_item_interior(item)
62
+ end
63
+ end
64
+
65
+ def render_item_span(item)
66
+ span(class: themed(:item_span)) do
67
+ render_item_interior(item)
68
+ end
69
+ end
70
+
71
+ def render_item_interior(item)
72
+ render_leading_badge(item.leading_badge) if item.leading_badge
73
+ render_icon(item.icon) if item.icon
74
+ render_label(item.label)
75
+ render_trailing_badge(item.trailing_badge) if item.trailing_badge
76
+ end
77
+
78
+ def render_label(label)
79
+ phlexi_render(label) {
80
+ span(class: themed(:item_label)) { label }
81
+ }
82
+ end
83
+
84
+ def render_leading_badge(badge)
85
+ phlexi_render(badge) {
86
+ span(class: themed(:leading_badge)) { badge }
87
+ }
88
+ end
89
+
90
+ def render_trailing_badge(badge)
91
+ phlexi_render(badge) {
92
+ span(class: themed(:trailing_badge)) { badge }
93
+ }
94
+ end
95
+
96
+ def render_icon(icon)
97
+ return unless icon
98
+
99
+ div(class: themed(:icon_wrapper)) do
100
+ render icon.new(class: themed(:icon))
101
+ end
102
+ end
103
+
104
+ def active_class(item)
105
+ item.active?(context) ? themed(:active) : nil
106
+ end
107
+
108
+ def item_parent_class(item)
109
+ item.items.any? ? themed(:item_parent) : nil
110
+ end
111
+
112
+ def themed(component)
113
+ self.class::Theme.instance.resolve_theme(component)
114
+ end
115
+
116
+ def phlexi_render(arg, &)
117
+ return unless arg
118
+ raise ArgumentError, "phlexi_render requires a default render block" unless block_given?
119
+
120
+ # Handle Phlex components or Rails Renderables
121
+ # if arg.is_a?(Class) && (arg < Phlex::SGML || arg.respond_to?(:render_in))
122
+ # render arg.new
123
+ # els
124
+ if arg.class < Phlex::SGML || arg.respond_to?(:render_in)
125
+ render arg
126
+ # Handle procs
127
+ elsif arg.respond_to?(:to_proc)
128
+ instance_exec(&arg)
129
+ else
130
+ yield
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Menu
5
+ class Item
6
+ attr_reader :label, :url, :icon, :leading_badge, :trailing_badge, :items, :options
7
+
8
+ def initialize(label, url: nil, icon: nil, leading_badge: nil, trailing_badge: nil, **options, &)
9
+ @label = label
10
+ @url = url
11
+ @icon = icon
12
+ @leading_badge = leading_badge
13
+ @trailing_badge = trailing_badge
14
+ @options = options
15
+ @items = []
16
+
17
+ yield self if block_given?
18
+ end
19
+
20
+ def item(label, **, &)
21
+ new_item = self.class.new(label, **, &)
22
+ @items << new_item
23
+ new_item
24
+ end
25
+
26
+ def active?(context)
27
+ # First check custom active logic if provided
28
+ return @options[:active].call(context) if @options[:active].respond_to?(:call)
29
+
30
+ # Then check if this item's URL matches current page
31
+ if context.respond_to?(:helpers) && @url
32
+ return true if context.helpers.current_page?(@url)
33
+ end
34
+
35
+ # Finally check if any child items are active
36
+ @items.any? { |item| item.active?(context) }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ require "phlexi-field"
2
+
3
+ module Phlexi
4
+ module Menu
5
+ class Theme < Phlexi::Field::Theme
6
+ def self.theme
7
+ @theme ||= {
8
+ nav: nil,
9
+ items_container: nil,
10
+ item_wrapper: nil,
11
+ item_parent: nil,
12
+ item_link: nil,
13
+ item_span: nil,
14
+ item_label: nil,
15
+ leading_badge: nil,
16
+ trailing_badge: nil,
17
+ icon: nil,
18
+ active: nil
19
+ }.freeze
20
+ end
21
+ end
22
+ end
23
+ end