hotwire_combobox 0.1.10 → 0.1.12
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/MIT-LICENSE +1 -1
- data/README.md +1 -4
- data/app/assets/javascripts/controllers/hw_combobox_controller.js +55 -211
- data/app/assets/javascripts/helpers.js +52 -0
- data/app/assets/javascripts/models/combobox/actors.js +24 -0
- data/app/assets/javascripts/models/combobox/async_loading.js +7 -0
- data/app/assets/javascripts/models/combobox/autocomplete.js +39 -0
- data/app/assets/javascripts/models/combobox/base.js +3 -0
- data/app/assets/javascripts/models/combobox/dialog.js +50 -0
- data/app/assets/javascripts/models/combobox/filtering.js +57 -0
- data/app/assets/javascripts/models/combobox/navigation.js +39 -0
- data/app/assets/javascripts/models/combobox/options.js +41 -0
- data/app/assets/javascripts/models/combobox/selection.js +62 -0
- data/app/assets/javascripts/models/combobox/toggle.js +104 -0
- data/app/assets/javascripts/models/combobox/validity.js +34 -0
- data/app/assets/javascripts/models/combobox.js +14 -0
- data/app/assets/javascripts/vendor/bodyScrollLock.js +299 -0
- data/app/assets/stylesheets/hotwire_combobox.css +181 -0
- data/app/helpers/hotwire_combobox/helper.rb +62 -73
- data/app/presenters/hotwire_combobox/component.rb +257 -0
- data/app/presenters/hotwire_combobox/listbox/option.rb +53 -0
- data/app/views/hotwire_combobox/_combobox.html.erb +5 -20
- data/app/views/hotwire_combobox/_next_page.turbo_stream.erb +5 -0
- data/app/views/hotwire_combobox/_paginated_options.turbo_stream.erb +7 -0
- data/app/views/hotwire_combobox/_pagination.html.erb +3 -0
- data/app/views/hotwire_combobox/combobox/_dialog.html.erb +7 -0
- data/app/views/hotwire_combobox/combobox/_hidden_field.html.erb +4 -0
- data/app/views/hotwire_combobox/combobox/_input.html.erb +2 -0
- data/app/views/hotwire_combobox/combobox/_paginated_listbox.html.erb +11 -0
- data/lib/hotwire_combobox/engine.rb +12 -2
- data/lib/hotwire_combobox/version.rb +1 -1
- data/lib/hotwire_combobox.rb +4 -2
- metadata +54 -2
@@ -2,104 +2,93 @@ module HotwireCombobox
|
|
2
2
|
module Helper
|
3
3
|
class << self
|
4
4
|
delegate :bypass_convenience_methods?, to: :HotwireCombobox
|
5
|
-
end
|
6
|
-
|
7
|
-
def hw_combobox_options(options)
|
8
|
-
options.map { |option| hw_combobox_option(**option) }
|
9
|
-
end
|
10
|
-
alias_method :combobox_options, :hw_combobox_options unless bypass_convenience_methods?
|
11
5
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
h[:data] = default_hw_combobox_value_field_data
|
17
|
-
h[:value] = form&.object&.public_send(name) || value
|
6
|
+
def hw(method_name)
|
7
|
+
unless bypass_convenience_methods?
|
8
|
+
alias_method method_name.to_s.sub(/^hw_/, ""), method_name
|
9
|
+
end
|
18
10
|
end
|
19
|
-
|
20
|
-
attrs[:type] ||= :text
|
21
|
-
attrs[:role] = :combobox
|
22
|
-
attrs[:id] = hw_combobox_id value_field_attrs[:id]
|
23
|
-
attrs[:data] = default_hw_combobox_data input.fetch(:data, {})
|
24
|
-
attrs[:aria] = default_hw_combobox_aria value_field_attrs, input.fetch(:aria, {})
|
25
|
-
|
26
|
-
render "hotwire_combobox/combobox", options: options,
|
27
|
-
attrs: attrs, value_field_attrs: value_field_attrs,
|
28
|
-
listbox_id: hw_combobox_listbox_id(value_field_attrs[:id]),
|
29
|
-
parent_data: default_hw_combobox_parent_data(attrs, data)
|
30
11
|
end
|
31
|
-
alias_method :combobox_tag, :hw_combobox_tag unless bypass_convenience_methods?
|
32
12
|
|
33
|
-
def
|
34
|
-
|
13
|
+
hw def hw_combobox_style_tag(*args, **kwargs)
|
14
|
+
stylesheet_link_tag HotwireCombobox.stylesheet_path, *args, **kwargs
|
35
15
|
end
|
36
16
|
|
37
|
-
def
|
38
|
-
|
17
|
+
hw def hw_combobox_tag(*args, async_src: nil, options: [], render_in: {}, **kwargs)
|
18
|
+
options = hw_combobox_options options, render_in: render_in
|
19
|
+
src = hw_uri_with_params async_src, format: :turbo_stream
|
20
|
+
component = HotwireCombobox::Component.new self, *args, options: options, async_src: src, **kwargs
|
21
|
+
|
22
|
+
render "hotwire_combobox/combobox", component: component
|
39
23
|
end
|
40
24
|
|
41
|
-
def
|
42
|
-
|
25
|
+
hw def hw_combobox_options(options, render_in: {}, display: :to_combobox_display, **methods)
|
26
|
+
if options.first.is_a? HotwireCombobox::Listbox::Option
|
27
|
+
options
|
28
|
+
else
|
29
|
+
content = if render_in.present?
|
30
|
+
->(object) { render(**render_in.merge(object: object)) }
|
31
|
+
else
|
32
|
+
methods[:content]
|
33
|
+
end
|
34
|
+
|
35
|
+
hw_parse_combobox_options options, **methods.merge(display: display, content: content)
|
36
|
+
end
|
43
37
|
end
|
44
38
|
|
45
|
-
def
|
46
|
-
|
39
|
+
hw def hw_paginated_combobox_options(options, for_id:, src:, next_page:, render_in: {}, **methods)
|
40
|
+
this_page = render("hotwire_combobox/paginated_options", for_id: for_id, options: hw_combobox_options(options, render_in: render_in, **methods), format: :turbo_stream)
|
41
|
+
next_page = render("hotwire_combobox/next_page", src: src, next_page: next_page, format: :turbo_stream)
|
42
|
+
|
43
|
+
safe_join [ this_page, next_page ]
|
47
44
|
end
|
48
45
|
|
49
|
-
def
|
50
|
-
|
46
|
+
hw def hw_listbox_options_id(id)
|
47
|
+
"#{id}-hw-listbox__options"
|
51
48
|
end
|
52
49
|
|
53
50
|
private
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
def default_hw_combobox_value_field_name(form, name)
|
63
|
-
form&.field_name(name) || name
|
64
|
-
end
|
65
|
-
|
66
|
-
def default_hw_combobox_value_field_data
|
67
|
-
{ "hw-combobox-target": "valueField" }
|
51
|
+
def hw_uri_with_params(url_or_path, **params)
|
52
|
+
URI.parse(url_or_path).tap do |url_or_path|
|
53
|
+
query = URI.decode_www_form(url_or_path.query || "").to_h.merge(params)
|
54
|
+
url_or_path.query = URI.encode_www_form query
|
55
|
+
end.to_s
|
56
|
+
rescue URI::InvalidURIError
|
57
|
+
url_or_path
|
68
58
|
end
|
69
59
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
keydown->hw-combobox#navigate
|
76
|
-
click@window->hw-combobox#closeOnClickOutside
|
77
|
-
focusin@window->hw-combobox#closeOnFocusOutside".squish,
|
78
|
-
"hw-combobox-target": "combobox"
|
60
|
+
def hw_parse_combobox_options(options, **methods)
|
61
|
+
options.map do |option|
|
62
|
+
attrs = option.is_a?(Hash) ? option : hw_option_attrs_for_obj(option, **methods)
|
63
|
+
HotwireCombobox::Listbox::Option.new **attrs
|
64
|
+
end
|
79
65
|
end
|
80
66
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
67
|
+
def hw_option_attrs_for_obj(option, **methods)
|
68
|
+
{}.tap do |attrs|
|
69
|
+
attrs[:id] = hw_call_method_or_proc(option, methods[:id]) if methods[:id]
|
70
|
+
attrs[:value] = hw_call_method_or_proc(option, methods[:value] || :id)
|
71
|
+
attrs[:display] = hw_call_method_or_proc(option, methods[:display]) if methods[:display]
|
72
|
+
attrs[:content] = hw_call_method_or_proc(option, methods[:content]) if methods[:content]
|
73
|
+
end
|
87
74
|
end
|
88
75
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
76
|
+
def hw_call_method_or_proc(object, method_or_proc)
|
77
|
+
if method_or_proc.is_a? Proc
|
78
|
+
method_or_proc.call object
|
79
|
+
else
|
80
|
+
object.public_send method_or_proc
|
81
|
+
end
|
95
82
|
end
|
96
83
|
|
97
|
-
def
|
98
|
-
|
84
|
+
def hw_combobox_next_page_uri(uri, next_page)
|
85
|
+
if next_page
|
86
|
+
hw_uri_with_params uri, page: next_page, q: params[:q], format: :turbo_stream
|
87
|
+
end
|
99
88
|
end
|
100
89
|
|
101
|
-
def
|
102
|
-
|
90
|
+
def hw_combobox_page_stream_action
|
91
|
+
params[:page] ? :append : :update
|
103
92
|
end
|
104
93
|
end
|
105
94
|
end
|
@@ -0,0 +1,257 @@
|
|
1
|
+
class HotwireCombobox::Component
|
2
|
+
attr_reader :async_src, :options, :dialog_label
|
3
|
+
|
4
|
+
def initialize(
|
5
|
+
view, name, value = nil,
|
6
|
+
autocomplete: :both,
|
7
|
+
id: nil,
|
8
|
+
form: nil,
|
9
|
+
name_when_new: nil,
|
10
|
+
open: false,
|
11
|
+
small_width: "640px",
|
12
|
+
async_src: nil,
|
13
|
+
dialog_label: nil,
|
14
|
+
options: [], data: {}, input: {}, **rest)
|
15
|
+
@combobox_attrs = input.reverse_merge(rest).with_indifferent_access
|
16
|
+
|
17
|
+
@view, @autocomplete, @id, @name, @value, @form, @async_src,
|
18
|
+
@name_when_new, @open, @data, @small_width, @options, @dialog_label =
|
19
|
+
view, autocomplete, id, name, value, form, async_src,
|
20
|
+
name_when_new, open, data, small_width, options, dialog_label
|
21
|
+
end
|
22
|
+
|
23
|
+
def fieldset_attrs
|
24
|
+
{
|
25
|
+
class: "hw-combobox",
|
26
|
+
data: fieldset_data
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def hidden_field_attrs
|
32
|
+
{
|
33
|
+
id: hidden_field_id,
|
34
|
+
name: hidden_field_name,
|
35
|
+
data: hidden_field_data,
|
36
|
+
value: hidden_field_value
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def input_attrs
|
42
|
+
nested_attrs = %i[ data aria ]
|
43
|
+
|
44
|
+
{
|
45
|
+
id: input_id,
|
46
|
+
role: :combobox,
|
47
|
+
class: "hw-combobox__input",
|
48
|
+
type: input_type,
|
49
|
+
data: input_data,
|
50
|
+
aria: input_aria
|
51
|
+
}.merge combobox_attrs.except(*nested_attrs)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def handle_attrs
|
56
|
+
{
|
57
|
+
class: "hw-combobox__handle",
|
58
|
+
data: handle_data
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def listbox_attrs
|
64
|
+
{
|
65
|
+
id: listbox_id,
|
66
|
+
role: :listbox,
|
67
|
+
class: "hw-combobox__listbox",
|
68
|
+
hidden: "",
|
69
|
+
data: listbox_data
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def listbox_options_attrs
|
75
|
+
{ id: listbox_options_id }
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def dialog_attrs
|
80
|
+
{
|
81
|
+
class: "hw-combobox__dialog",
|
82
|
+
role: :dialog,
|
83
|
+
data: dialog_data
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def dialog_label_attrs
|
88
|
+
{
|
89
|
+
class: "hw-combobox__dialog__label",
|
90
|
+
for: dialog_input_id
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def dialog_input_attrs
|
95
|
+
{
|
96
|
+
id: dialog_input_id,
|
97
|
+
role: :combobox,
|
98
|
+
class: "hw-combobox__dialog__input",
|
99
|
+
autofocus: "",
|
100
|
+
type: input_type,
|
101
|
+
data: dialog_input_data,
|
102
|
+
aria: dialog_input_aria
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def dialog_listbox_attrs
|
107
|
+
{
|
108
|
+
id: dialog_listbox_id,
|
109
|
+
class: "hw-combobox__dialog__listbox",
|
110
|
+
role: :listbox,
|
111
|
+
data: dialog_listbox_data
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
def dialog_focus_trap_attrs
|
116
|
+
{
|
117
|
+
tabindex: "-1",
|
118
|
+
data: dialog_focus_trap_data
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def paginated?
|
124
|
+
async_src.present?
|
125
|
+
end
|
126
|
+
|
127
|
+
def pagination_attrs
|
128
|
+
{ src: async_src }
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
attr_reader :view, :autocomplete, :id, :name, :value, :form,
|
133
|
+
:name_when_new, :open, :data, :combobox_attrs, :small_width
|
134
|
+
|
135
|
+
def fieldset_data
|
136
|
+
data.reverse_merge \
|
137
|
+
controller: view.token_list("hw-combobox", data[:controller]),
|
138
|
+
hw_combobox_expanded_value: open,
|
139
|
+
hw_combobox_name_when_new_value: name_when_new,
|
140
|
+
hw_combobox_original_name_value: hidden_field_name,
|
141
|
+
hw_combobox_autocomplete_value: autocomplete,
|
142
|
+
hw_combobox_small_viewport_max_width_value: small_width,
|
143
|
+
hw_combobox_async_src_value: async_src,
|
144
|
+
hw_combobox_filterable_attribute_value: "data-filterable-as",
|
145
|
+
hw_combobox_autocompletable_attribute_value: "data-autocompletable-as",
|
146
|
+
hw_combobox_selected_class: "hw-combobox__option--selected"
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def hidden_field_id
|
151
|
+
id || form&.field_id(name)
|
152
|
+
end
|
153
|
+
|
154
|
+
def hidden_field_name
|
155
|
+
form&.field_name(name) || name
|
156
|
+
end
|
157
|
+
|
158
|
+
def hidden_field_data
|
159
|
+
{ hw_combobox_target: "hiddenField" }
|
160
|
+
end
|
161
|
+
|
162
|
+
def hidden_field_value
|
163
|
+
form&.object&.public_send(name) || value
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def input_id
|
168
|
+
"#{hidden_field_id}-hw-combobox"
|
169
|
+
end
|
170
|
+
|
171
|
+
def input_type
|
172
|
+
combobox_attrs[:type].to_s.presence_in(%w[ text search ]) || "text"
|
173
|
+
end
|
174
|
+
|
175
|
+
def input_data
|
176
|
+
combobox_attrs.fetch(:data, {}).reverse_merge! \
|
177
|
+
action: "
|
178
|
+
focus->hw-combobox#open
|
179
|
+
input->hw-combobox#filter
|
180
|
+
keydown->hw-combobox#navigate
|
181
|
+
click@window->hw-combobox#closeOnClickOutside
|
182
|
+
focusin@window->hw-combobox#closeOnFocusOutside".squish,
|
183
|
+
hw_combobox_target: "combobox"
|
184
|
+
end
|
185
|
+
|
186
|
+
def input_aria
|
187
|
+
combobox_attrs.fetch(:aria, {}).reverse_merge! \
|
188
|
+
controls: listbox_id,
|
189
|
+
owns: listbox_id,
|
190
|
+
haspopup: "listbox",
|
191
|
+
autocomplete: autocomplete
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
def handle_data
|
196
|
+
{
|
197
|
+
action: "click->hw-combobox#toggle",
|
198
|
+
hw_combobox_target: "handle"
|
199
|
+
}
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
def listbox_id
|
204
|
+
"#{hidden_field_id}-hw-listbox"
|
205
|
+
end
|
206
|
+
|
207
|
+
def listbox_data
|
208
|
+
{ hw_combobox_target: "listbox" }
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
def listbox_options_id
|
213
|
+
"#{listbox_id}__options"
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
def dialog_data
|
218
|
+
{
|
219
|
+
action: "keydown->hw-combobox#navigate",
|
220
|
+
hw_combobox_target: "dialog"
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
def dialog_input_id
|
225
|
+
"#{hidden_field_id}-hw-dialog-combobox"
|
226
|
+
end
|
227
|
+
|
228
|
+
def dialog_input_data
|
229
|
+
{
|
230
|
+
action: "
|
231
|
+
input->hw-combobox#filter
|
232
|
+
keydown->hw-combobox#navigate
|
233
|
+
click@window->hw-combobox#closeOnClickOutside".squish,
|
234
|
+
hw_combobox_target: "dialogCombobox"
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
def dialog_input_aria
|
239
|
+
{
|
240
|
+
controls: dialog_listbox_id,
|
241
|
+
owns: dialog_listbox_id,
|
242
|
+
autocomplete: autocomplete
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
def dialog_listbox_id
|
247
|
+
"#{hidden_field_id}-hw-dialog-listbox"
|
248
|
+
end
|
249
|
+
|
250
|
+
def dialog_listbox_data
|
251
|
+
{ hw_combobox_target: "dialogListbox" }
|
252
|
+
end
|
253
|
+
|
254
|
+
def dialog_focus_trap_data
|
255
|
+
{ hw_combobox_target: "dialogFocusTrap" }
|
256
|
+
end
|
257
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class HotwireCombobox::Listbox::Option
|
2
|
+
def initialize(option)
|
3
|
+
@option = option.is_a?(Hash) ? Data.new(**option) : option
|
4
|
+
end
|
5
|
+
|
6
|
+
def render_in(view_context)
|
7
|
+
view_context.tag.li content, **options
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
Data = Struct.new :id, :value, :display, :content, :filterable_as, :autocompletable_as, keyword_init: true
|
12
|
+
|
13
|
+
attr_reader :option
|
14
|
+
|
15
|
+
def content
|
16
|
+
option.try(:content) || option.try(:display)
|
17
|
+
end
|
18
|
+
|
19
|
+
def options
|
20
|
+
{
|
21
|
+
id: id,
|
22
|
+
role: :option,
|
23
|
+
class: "hw-combobox__option",
|
24
|
+
tabindex: 0,
|
25
|
+
data: data
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def id
|
30
|
+
option.try(:id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def data
|
34
|
+
{
|
35
|
+
action: "click->hw-combobox#selectOption",
|
36
|
+
filterable_as: filterable_as,
|
37
|
+
autocompletable_as: autocompletable_as,
|
38
|
+
value: value
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def filterable_as
|
43
|
+
option.try(:filterable_as) || option.try(:display)
|
44
|
+
end
|
45
|
+
|
46
|
+
def autocompletable_as
|
47
|
+
option.try(:autocompletable_as) || option.try(:display)
|
48
|
+
end
|
49
|
+
|
50
|
+
def value
|
51
|
+
option.try(:value) || option.id
|
52
|
+
end
|
53
|
+
end
|
@@ -1,21 +1,6 @@
|
|
1
|
-
<%= tag.fieldset
|
2
|
-
<%=
|
3
|
-
|
4
|
-
|
5
|
-
<%=
|
6
|
-
|
7
|
-
<%= tag.ul id: listbox_id, hidden: "", role: :listbox,
|
8
|
-
data: { "hw-combobox-target": "listbox" } do |ul| %>
|
9
|
-
<% options.each do |option| %>
|
10
|
-
<%= tag.li hw_listbox_option_content(option),
|
11
|
-
id: hw_listbox_option_id(option),
|
12
|
-
role: :option,
|
13
|
-
style: "cursor: pointer;",
|
14
|
-
data: {
|
15
|
-
"action": "click->hw-combobox#selectOption",
|
16
|
-
"filterable-as": hw_listbox_option_filterable_as(option),
|
17
|
-
"autocompletable-as": hw_listbox_option_autocompletable_as(option),
|
18
|
-
"value": hw_listbox_option_value(option) } %>
|
19
|
-
<% end %>
|
20
|
-
<% end %>
|
1
|
+
<%= tag.fieldset **component.fieldset_attrs do %>
|
2
|
+
<%= render "hotwire_combobox/combobox/hidden_field", component: component %>
|
3
|
+
<%= render "hotwire_combobox/combobox/input", component: component %>
|
4
|
+
<%= render "hotwire_combobox/combobox/paginated_listbox", component: component %>
|
5
|
+
<%= render "hotwire_combobox/combobox/dialog", component: component %>
|
21
6
|
<% end %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<%= tag.div **component.dialog_focus_trap_attrs %>
|
2
|
+
|
3
|
+
<%= tag.dialog **component.dialog_attrs do %>
|
4
|
+
<%= tag.label component.dialog_label, **component.dialog_label_attrs %>
|
5
|
+
<%= tag.input **component.dialog_input_attrs %>
|
6
|
+
<%= tag.ul **component.dialog_listbox_attrs %>
|
7
|
+
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= tag.ul **component.listbox_attrs do |ul| %>
|
2
|
+
<%= tag.div **component.listbox_options_attrs do %>
|
3
|
+
<% component.options.each do |option| %>
|
4
|
+
<%= render option %>
|
5
|
+
<% end %>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<% if component.paginated? %>
|
9
|
+
<%= render "hotwire_combobox/pagination", **component.pagination_attrs %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
@@ -3,8 +3,18 @@ module HotwireCombobox
|
|
3
3
|
isolate_namespace HotwireCombobox
|
4
4
|
|
5
5
|
initializer "hotwire_combobox.view_helpers" do
|
6
|
-
ActiveSupport.on_load :
|
7
|
-
|
6
|
+
ActiveSupport.on_load :action_view do
|
7
|
+
include HotwireCombobox::Helper
|
8
|
+
|
9
|
+
unless HotwireCombobox.bypass_convenience_methods?
|
10
|
+
module FormBuilderExtensions
|
11
|
+
def combobox(*args, **kwargs, &block)
|
12
|
+
@template.hw_combobox_tag *args, **kwargs.merge(form: self), &block
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ActionView::Helpers::FormBuilder.include FormBuilderExtensions
|
17
|
+
end
|
8
18
|
end
|
9
19
|
end
|
10
20
|
|
data/lib/hotwire_combobox.rb
CHANGED
@@ -2,8 +2,6 @@ require "hotwire_combobox/version"
|
|
2
2
|
require "hotwire_combobox/engine"
|
3
3
|
|
4
4
|
module HotwireCombobox
|
5
|
-
Option = Struct.new(:id, :value, :display, :content, :filterable_as, :autocompletable_as)
|
6
|
-
|
7
5
|
mattr_accessor :bypass_convenience_methods
|
8
6
|
@@bypass_convenience_methods = false
|
9
7
|
|
@@ -15,5 +13,9 @@ module HotwireCombobox
|
|
15
13
|
def bypass_convenience_methods?
|
16
14
|
bypass_convenience_methods
|
17
15
|
end
|
16
|
+
|
17
|
+
def stylesheet_path
|
18
|
+
"hotwire_combobox"
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|