phlexi-menu 0.0.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.
@@ -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