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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddf9dd6a046c3871c1b3935a8a2e9e899a88787ba6d39e673ec8eee792c920dc
4
- data.tar.gz: f6d207f71a8ce4779df0cc12cd4264106b1fb086319bc8ad4c303a22604f2f1c
3
+ metadata.gz: 9649cc031cc63f665e78c4f72857f72698d42af893d8204cab739a5817be27b8
4
+ data.tar.gz: f9e791cc61927caebd9db3c32cf3e71382f6d77e4f54c8275348b02600fce8d4
5
5
  SHA512:
6
- metadata.gz: 5cb541bd15115ee71ed82dea3d2c922abcd9c8279f835b7d6074fd825cbd08e6ac40d1b181b398ee6d00a1e4c7d7fc3f18892134cc362aa98640519ee27b9030
7
- data.tar.gz: a6adeb3593a0f25d9a726be101c52c00488d367592d134c089d520cc6a087eff67f00b5f965fcc8b1c09e6c1f6f96e955815d234cdc19162a1dc657a83271183
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 Tests](https://github.com/josefarias/hotwire_combobox/actions/workflows/ci_tests.yml/badge.svg)](https://github.com/josefarias/hotwire_combobox/actions/workflows/ci_tests.yml) [![Gem Version](https://badge.fury.io/rb/hotwire_combobox.svg)](https://badge.fury.io/rb/hotwire_combobox)
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]
@@ -65,6 +65,10 @@ export default class HwComboboxController extends Concerns(...concerns) {
65
65
  }
66
66
 
67
67
  connect() {
68
+ this.idempotentConnect()
69
+ }
70
+
71
+ idempotentConnect() {
68
72
  this._connectSelection()
69
73
  this._connectListAutocomplete()
70
74
  this._connectDialog()
@@ -1,5 +1,5 @@
1
1
  /*!
2
- HotwireCombobox 0.2.0
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.0
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: 0;
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-visible {
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 hidden_field_value
246
- options.find { |option| option.value == hidden_field_value }&.autocompletable_as
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
- form.object.public_send association_name
254
+ form_object&.public_send association_name
253
255
  end
254
256
  end
255
257
 
256
258
  def association_exists?
257
- form&.object&.class&.reflect_on_association(association_name).present?
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 form&.object&.defined_enums&.try :[], name
306
- form.object.public_send "#{name}_before_type_cast"
311
+ if form_object&.defined_enums&.try :[], name
312
+ form_object.public_send "#{name}_before_type_cast"
307
313
  else
308
- form&.object&.try(name).then do |value|
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".squish,
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, :options
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).items
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 items
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
- key, value = options.to_a.first
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.map do |option|
47
- HotwireCombobox::Listbox::Option.new **option_attrs(option)
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
- if include_blank.is_a? Hash
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
- else
105
+ when String
101
106
  [ include_blank, include_blank ]
107
+ else
108
+ [ "", "&nbsp;".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
- if options.first.is_a? HotwireCombobox::Listbox::Option
30
- options
31
- else
32
- HotwireCombobox::Listbox::Item.collection_for \
33
- self,
34
- options,
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
@@ -1,3 +1,3 @@
1
1
  module HotwireCombobox
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  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.0
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-22 00:00:00.000000000 Z
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.5.6
133
+ rubygems_version: 3.4.18
133
134
  signing_key:
134
135
  specification_version: 4
135
136
  summary: Accessible Autocomplete for Rails apps