hotwire_combobox 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/controllers/hw_combobox_controller.js +4 -0
- data/app/assets/javascripts/hotwire_combobox.esm.js +5 -1
- data/app/assets/javascripts/hotwire_combobox.umd.js +5 -1
- data/app/assets/stylesheets/hotwire_combobox.css +7 -2
- data/app/presenters/hotwire_combobox/component.rb +16 -9
- data/app/presenters/hotwire_combobox/listbox/group.rb +3 -1
- data/app/presenters/hotwire_combobox/listbox/item/collection.rb +14 -0
- data/app/presenters/hotwire_combobox/listbox/item.rb +15 -8
- data/app/presenters/hotwire_combobox/listbox/option.rb +4 -4
- data/lib/hotwire_combobox/helper.rb +7 -11
- data/lib/hotwire_combobox/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9649cc031cc63f665e78c4f72857f72698d42af893d8204cab739a5817be27b8
|
4
|
+
data.tar.gz: f9e791cc61927caebd9db3c32cf3e71382f6d77e4f54c8275348b02600fce8d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f6c132e19554295758e13763663a6e0d3b0e7a0a413088a25aed723370dd5967133af3e2660e9ef4ecb16d661f39232bb36ac9c08c37531b36677f2a8c0d961
|
7
|
+
data.tar.gz: 6461c5650345338c17dd33dd378575d5376e2b31ed9466aa4b527096ae831db8feac8b73f357dc8da7908dd7e41aeed1a6750bd9bc1cd570c6e5634562aca0f9
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# Easy and Accessible Autocomplete for Ruby on Rails
|
6
6
|
|
7
|
-
[![CI
|
7
|
+
[![CI](https://github.com/josefarias/hotwire_combobox/actions/workflows/ci.yml/badge.svg)](https://github.com/josefarias/hotwire_combobox/actions/workflows/ci.yml) [![Gem Version](https://badge.fury.io/rb/hotwire_combobox.svg)](https://badge.fury.io/rb/hotwire_combobox)
|
8
8
|
|
9
9
|
|
10
10
|
> [!IMPORTANT]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
HotwireCombobox 0.2.
|
2
|
+
HotwireCombobox 0.2.1
|
3
3
|
*/
|
4
4
|
import { Controller } from '@hotwired/stimulus';
|
5
5
|
|
@@ -1706,6 +1706,10 @@ class HwComboboxController extends Concerns(...concerns) {
|
|
1706
1706
|
}
|
1707
1707
|
|
1708
1708
|
connect() {
|
1709
|
+
this.idempotentConnect();
|
1710
|
+
}
|
1711
|
+
|
1712
|
+
idempotentConnect() {
|
1709
1713
|
this._connectSelection();
|
1710
1714
|
this._connectListAutocomplete();
|
1711
1715
|
this._connectDialog();
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
HotwireCombobox 0.2.
|
2
|
+
HotwireCombobox 0.2.1
|
3
3
|
*/
|
4
4
|
(function (global, factory) {
|
5
5
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@hotwired/stimulus')) :
|
@@ -1710,6 +1710,10 @@ HotwireCombobox 0.2.0
|
|
1710
1710
|
}
|
1711
1711
|
|
1712
1712
|
connect() {
|
1713
|
+
this.idempotentConnect();
|
1714
|
+
}
|
1715
|
+
|
1716
|
+
idempotentConnect() {
|
1713
1717
|
this._connectSelection();
|
1714
1718
|
this._connectListAutocomplete();
|
1715
1719
|
this._connectDialog();
|
@@ -2,6 +2,7 @@
|
|
2
2
|
--hw-active-bg-color: #F3F4F6;
|
3
3
|
--hw-border-color: #D1D5DB;
|
4
4
|
--hw-group-color: #57595C;
|
5
|
+
--hw-group-bg-color: #FFFFFF;
|
5
6
|
--hw-invalid-color: #EF4444;
|
6
7
|
--hw-dialog-label-color: #1D1D1D;
|
7
8
|
--hw-focus-color: #2563EB;
|
@@ -78,7 +79,7 @@
|
|
78
79
|
}
|
79
80
|
|
80
81
|
.hw-combobox__input {
|
81
|
-
border:
|
82
|
+
border: none;
|
82
83
|
font-size: inherit;
|
83
84
|
line-height: var(--hw-line-height);
|
84
85
|
min-width: 0;
|
@@ -87,7 +88,10 @@
|
|
87
88
|
width: 100%;
|
88
89
|
}
|
89
90
|
|
90
|
-
.hw-combobox__input:focus
|
91
|
+
.hw-combobox__input:focus,
|
92
|
+
.hw-combobox__input:focus-visible,
|
93
|
+
.hw-combobox__input:focus-within {
|
94
|
+
box-shadow: none;
|
91
95
|
outline: none;
|
92
96
|
}
|
93
97
|
|
@@ -145,6 +149,7 @@
|
|
145
149
|
}
|
146
150
|
|
147
151
|
.hw-combobox__group__label {
|
152
|
+
background-color: var(--hw-group-bg-color);
|
148
153
|
color: var(--hw-group-color);
|
149
154
|
padding: var(--hw-padding--slim);
|
150
155
|
}
|
@@ -238,23 +238,29 @@ class HotwireCombobox::Component
|
|
238
238
|
end
|
239
239
|
|
240
240
|
def prefilled_display
|
241
|
-
return if multiselect?
|
241
|
+
return if multiselect? || !hidden_field_value
|
242
242
|
|
243
243
|
if async_src && associated_object
|
244
244
|
associated_object.to_combobox_display
|
245
|
-
elsif
|
246
|
-
|
245
|
+
elsif async_src && form_object&.respond_to?(name)
|
246
|
+
form_object.public_send name
|
247
|
+
else
|
248
|
+
options.find_by_value(hidden_field_value)&.autocompletable_as
|
247
249
|
end
|
248
250
|
end
|
249
251
|
|
250
252
|
def associated_object
|
251
253
|
@associated_object ||= if association_exists?
|
252
|
-
|
254
|
+
form_object&.public_send association_name
|
253
255
|
end
|
254
256
|
end
|
255
257
|
|
256
258
|
def association_exists?
|
257
|
-
|
259
|
+
form_object&.class&.reflect_on_association(association_name).present?
|
260
|
+
end
|
261
|
+
|
262
|
+
def form_object
|
263
|
+
form&.object
|
258
264
|
end
|
259
265
|
|
260
266
|
def async_src
|
@@ -302,10 +308,10 @@ class HotwireCombobox::Component
|
|
302
308
|
def hidden_field_value
|
303
309
|
return value if value
|
304
310
|
|
305
|
-
if
|
306
|
-
|
311
|
+
if form_object&.defined_enums&.try :[], name
|
312
|
+
form_object.public_send "#{name}_before_type_cast"
|
307
313
|
else
|
308
|
-
|
314
|
+
form_object&.try(name).then do |value|
|
309
315
|
value.respond_to?(:map) ? value.join(",") : value
|
310
316
|
end
|
311
317
|
end
|
@@ -329,7 +335,8 @@ class HotwireCombobox::Component
|
|
329
335
|
click@window->hw-combobox#closeOnClickOutside
|
330
336
|
focusin@window->hw-combobox#closeOnFocusOutside
|
331
337
|
turbo:before-stream-render@document->hw-combobox#rerouteListboxStreamToDialog
|
332
|
-
turbo:before-cache@document->hw-combobox#hideChipsForCache
|
338
|
+
turbo:before-cache@document->hw-combobox#hideChipsForCache
|
339
|
+
turbo:morph-element->hw-combobox#idempotentConnect".squish,
|
333
340
|
hw_combobox_target: "combobox",
|
334
341
|
async_id: canonical_id
|
335
342
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require "securerandom"
|
2
2
|
|
3
3
|
class HotwireCombobox::Listbox::Group
|
4
|
+
attr_reader :options
|
5
|
+
|
4
6
|
def initialize(name, options:)
|
5
7
|
@name = name
|
6
8
|
@options = options
|
@@ -17,7 +19,7 @@ class HotwireCombobox::Listbox::Group
|
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
|
-
attr_reader :name
|
22
|
+
attr_reader :name
|
21
23
|
|
22
24
|
def id
|
23
25
|
@id ||= SecureRandom.uuid
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class HotwireCombobox::Listbox::Item::Collection < Array
|
2
|
+
def find_by_value(value)
|
3
|
+
if grouped?
|
4
|
+
flat_map { |item| item.options }.find { |option| option.value == value }
|
5
|
+
else
|
6
|
+
find { |option| option.value == value }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def grouped?
|
12
|
+
first.is_a? HotwireCombobox::Listbox::Group
|
13
|
+
end
|
14
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class HotwireCombobox::Listbox::Item
|
2
2
|
class << self
|
3
3
|
def collection_for(view, options, render_in:, include_blank:, **custom_methods)
|
4
|
-
new(view, options, render_in: render_in, include_blank: include_blank, **custom_methods).
|
4
|
+
new(view, options, render_in: render_in, include_blank: include_blank, **custom_methods).collection
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
@@ -13,10 +13,10 @@ class HotwireCombobox::Listbox::Item
|
|
13
13
|
@custom_methods = custom_methods
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def collection
|
17
17
|
items = groups_or_options
|
18
18
|
items.unshift(blank_option) if include_blank.present?
|
19
|
-
items
|
19
|
+
Collection.new items
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
@@ -31,7 +31,7 @@ class HotwireCombobox::Listbox::Item
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def grouped?
|
34
|
-
|
34
|
+
_key, value = options.to_a.first
|
35
35
|
value.is_a? Array
|
36
36
|
end
|
37
37
|
|
@@ -43,8 +43,12 @@ class HotwireCombobox::Listbox::Item
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def create_listbox_options(options)
|
46
|
-
options.
|
47
|
-
|
46
|
+
if options.first.is_a? HotwireCombobox::Listbox::Option
|
47
|
+
options
|
48
|
+
else
|
49
|
+
options.map do |option|
|
50
|
+
HotwireCombobox::Listbox::Option.new **option_attrs(option)
|
51
|
+
end
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -93,12 +97,15 @@ class HotwireCombobox::Listbox::Item
|
|
93
97
|
end
|
94
98
|
|
95
99
|
def extract_blank_display_and_content
|
96
|
-
|
100
|
+
case include_blank
|
101
|
+
when Hash
|
97
102
|
text = include_blank.delete(:text)
|
98
103
|
|
99
104
|
[ text, render_content(render_opts: include_blank, object: text, attrs: { display: text, value: "" }) ]
|
100
|
-
|
105
|
+
when String
|
101
106
|
[ include_blank, include_blank ]
|
107
|
+
else
|
108
|
+
[ "", " ".html_safe ]
|
102
109
|
end
|
103
110
|
end
|
104
111
|
end
|
@@ -17,10 +17,6 @@ class HotwireCombobox::Listbox::Option
|
|
17
17
|
option.try(:autocompletable_as) || option.try(:display)
|
18
18
|
end
|
19
19
|
|
20
|
-
def content
|
21
|
-
option.try(:content) || option.try(:display)
|
22
|
-
end
|
23
|
-
|
24
20
|
private
|
25
21
|
Data = Struct.new :id, :value, :display, :content, :blank, :filterable_as, :autocompletable_as, keyword_init: true
|
26
22
|
|
@@ -57,6 +53,10 @@ class HotwireCombobox::Listbox::Option
|
|
57
53
|
option.try(:filterable_as) || option.try(:display)
|
58
54
|
end
|
59
55
|
|
56
|
+
def content
|
57
|
+
option.try(:content) || option.try(:display)
|
58
|
+
end
|
59
|
+
|
60
60
|
def blank?
|
61
61
|
option.try(:blank).present?
|
62
62
|
end
|
@@ -26,16 +26,12 @@ module HotwireCombobox
|
|
26
26
|
include_blank: nil,
|
27
27
|
display: :to_combobox_display,
|
28
28
|
**custom_methods)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
render_in: render_in,
|
36
|
-
include_blank: include_blank,
|
37
|
-
**custom_methods.merge(display: display)
|
38
|
-
end
|
29
|
+
HotwireCombobox::Listbox::Item.collection_for \
|
30
|
+
self,
|
31
|
+
options,
|
32
|
+
render_in: render_in,
|
33
|
+
include_blank: include_blank,
|
34
|
+
**custom_methods.merge(display: display)
|
39
35
|
end
|
40
36
|
|
41
37
|
def hw_paginated_combobox_options(
|
@@ -184,7 +180,7 @@ module HotwireCombobox
|
|
184
180
|
private
|
185
181
|
def hw_extract_options_and_src(options_or_src, render_in, include_blank)
|
186
182
|
if options_or_src.is_a? String
|
187
|
-
[ [], options_or_src ]
|
183
|
+
[ hw_combobox_options([]), options_or_src ]
|
188
184
|
else
|
189
185
|
[ hw_combobox_options(options_or_src, render_in: render_in, include_blank: include_blank), nil ]
|
190
186
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotwire_combobox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jose Farias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- app/presenters/hotwire_combobox/component/customizable.rb
|
92
92
|
- app/presenters/hotwire_combobox/listbox/group.rb
|
93
93
|
- app/presenters/hotwire_combobox/listbox/item.rb
|
94
|
+
- app/presenters/hotwire_combobox/listbox/item/collection.rb
|
94
95
|
- app/presenters/hotwire_combobox/listbox/option.rb
|
95
96
|
- app/views/hotwire_combobox/_component.html.erb
|
96
97
|
- app/views/hotwire_combobox/_next_page.turbo_stream.erb
|
@@ -129,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
130
|
- !ruby/object:Gem::Version
|
130
131
|
version: '0'
|
131
132
|
requirements: []
|
132
|
-
rubygems_version: 3.
|
133
|
+
rubygems_version: 3.4.18
|
133
134
|
signing_key:
|
134
135
|
specification_version: 4
|
135
136
|
summary: Accessible Autocomplete for Rails apps
|