hotwire_combobox 0.1.33 → 0.1.34

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: 415f50ba9630121312ea65c8f04435ff57ba386ffb9851dc9e09da8a6dc68352
4
- data.tar.gz: de3d2d2bfb9d9f9e21292acf49152484ad05317b16daade967ea695afbf3bc87
3
+ metadata.gz: d3bf6f83f984a36fb6e0491f68a71c9386c3f2a00e6b6082cd490b73e58d652d
4
+ data.tar.gz: db089a58628fa02b4a173f18053a9a81a21402eeafdcfb943d403989597bf314
5
5
  SHA512:
6
- metadata.gz: aab8d6575ec896e26035b5040afa0765b3dacd92d101589b20f305840a5831174cad852325bc64971e83f182260454d2d836be665f19a33cf845d972d90b8134
7
- data.tar.gz: 5f4393d0d3dbf29c9bf194210cf7d845c35062a7fd4d952e6acafae2c407ce158d63735f703419311c15ab3996002fa573617cbff26b98406d7e98bdf0e85e9f
6
+ metadata.gz: '0483ae80475b1d52b9b74d21c5749ee0300914954f74e40267de50cfb96dbb77e44a8bdfb5448caf9d743798e2621d678986927c5f201c40052e049c2844a13f'
7
+ data.tar.gz: 594db1df1c85dd096ca2cebf2ff9a7dc6564e061aee5f4403729eb94eaf55ab587f32ea620b0f359bd5f1c41e2e4c70096fb5ef04230a07ee13d6cda7873cd33
data/README.md CHANGED
@@ -22,10 +22,6 @@ Only apps that use importmaps are currently supported. Suport for other JS solut
22
22
 
23
23
  ## Docs
24
24
 
25
- <p align="center">
26
- <img src="docs/assets/images/docs-preview.png" height=500>
27
- </p>
28
-
29
25
  Visit [the docs site](https://hotwirecombobox.com/) for a demo and detailed documentation.
30
26
  If the site is down, you can run the docs locally by cloning [the docs repo](https://github.com/josefarias/hotwire_combobox_docs).
31
27
 
@@ -29,10 +29,10 @@ export default class HwComboboxController extends Concerns(...concerns) {
29
29
  "dialogCombobox",
30
30
  "dialogFocusTrap",
31
31
  "dialogListbox",
32
+ "endOfOptionsStream",
32
33
  "handle",
33
34
  "hiddenField",
34
- "listbox",
35
- "paginationFrame"
35
+ "listbox"
36
36
  ]
37
37
 
38
38
  static values = {
@@ -70,7 +70,13 @@ export default class HwComboboxController extends Concerns(...concerns) {
70
70
  }
71
71
  }
72
72
 
73
- paginationFrameTargetConnected() {
73
+ endOfOptionsStreamTargetConnected(element) {
74
+ const inputType = element.dataset.inputType
75
+
74
76
  this._preselectOption()
77
+
78
+ if (inputType) {
79
+ this._commitFilter({ inputType })
80
+ }
75
81
  }
76
82
  }
@@ -39,10 +39,6 @@ export function startsWith(string, substring) {
39
39
  return string.toLowerCase().startsWith(substring.toLowerCase())
40
40
  }
41
41
 
42
- export function nextFrame() {
43
- return new Promise(requestAnimationFrame)
44
- }
45
-
46
42
  export function debounce(fn, delay = 150) {
47
43
  let timeoutId = null
48
44
 
@@ -8,17 +8,17 @@ Combobox.Autocomplete = Base => class extends Base {
8
8
  }
9
9
  }
10
10
 
11
- _maybeAutocompleteWith(option, { force }) {
11
+ _autocompleteWith(option, { force }) {
12
12
  if (!this._autocompletesInline && !force) return
13
13
 
14
- const typedValue = this._actingCombobox.value
14
+ const typedValue = this._query
15
15
  const autocompletedValue = option.getAttribute(this.autocompletableAttributeValue)
16
16
 
17
17
  if (force) {
18
- this._actingCombobox.value = autocompletedValue
18
+ this._query = autocompletedValue
19
19
  this._actingCombobox.setSelectionRange(autocompletedValue.length, autocompletedValue.length)
20
20
  } else if (startsWith(autocompletedValue, typedValue)) {
21
- this._actingCombobox.value = autocompletedValue
21
+ this._query = autocompletedValue
22
22
  this._actingCombobox.setSelectionRange(typedValue.length, autocompletedValue.length)
23
23
  }
24
24
  }
@@ -30,14 +30,14 @@ Combobox.Autocomplete = Base => class extends Base {
30
30
  }
31
31
 
32
32
  get _isExactAutocompleteMatch() {
33
- return this._immediatelyAutocompletableValue === this._actingCombobox.value
33
+ return this._immediatelyAutocompletableValue === this._query
34
34
  }
35
35
 
36
36
  // All `_isExactAutocompleteMatch` matches are `_isPartialAutocompleteMatch` matches
37
37
  // but not all `_isPartialAutocompleteMatch` matches are `_isExactAutocompleteMatch` matches.
38
38
  get _isPartialAutocompleteMatch() {
39
39
  return !!this._immediatelyAutocompletableValue &&
40
- startsWith(this._immediatelyAutocompletableValue, this._actingCombobox.value)
40
+ startsWith(this._immediatelyAutocompletableValue, this._query)
41
41
  }
42
42
 
43
43
  get _autocompletesList() {
@@ -14,7 +14,7 @@ Combobox.Dialog = Base => class extends Base {
14
14
  }
15
15
 
16
16
  _moveArtifactsToDialog() {
17
- this.dialogComboboxTarget.value = this._actingCombobox.value
17
+ this.dialogComboboxTarget.value = this._query
18
18
 
19
19
  this._actingCombobox = this.dialogComboboxTarget
20
20
  this._actingListbox = this.dialogListboxTarget
@@ -23,7 +23,7 @@ Combobox.Dialog = Base => class extends Base {
23
23
  }
24
24
 
25
25
  _moveArtifactsInline() {
26
- this.comboboxTarget.value = this._actingCombobox.value
26
+ this.comboboxTarget.value = this._query
27
27
 
28
28
  this._actingCombobox = this.comboboxTarget
29
29
  this._actingListbox = this.listboxTarget
@@ -1,6 +1,6 @@
1
1
 
2
2
  import Combobox from "hw_combobox/models/combobox/base"
3
- import { applyFilter, nextFrame, debounce, isDeleteEvent } from "hw_combobox/helpers"
3
+ import { applyFilter, debounce, isDeleteEvent } from "hw_combobox/helpers"
4
4
  import { get } from "hw_combobox/vendor/requestjs"
5
5
 
6
6
  Combobox.Filtering = Base => class extends Base {
@@ -21,20 +21,13 @@ Combobox.Filtering = Base => class extends Base {
21
21
  }
22
22
 
23
23
  async _filterAsync(event) {
24
- const q = this._actingCombobox.value.trim()
25
-
26
- await get(this.asyncSrcValue, { responseKind: "turbo-stream", query: { q } })
27
-
28
- this._afterTurboStreamRender(() => this._commitFilter(event))
24
+ const query = { q: this._query, input_type: event.inputType }
25
+ await get(this.asyncSrcValue, { responseKind: "turbo-stream", query })
29
26
  }
30
27
 
31
28
  _filterSync(event) {
32
- const query = this._actingCombobox.value.trim()
33
-
34
29
  this.open()
35
-
36
- this._allOptionElements.forEach(applyFilter(query, { matching: this.filterableAttributeValue }))
37
-
30
+ this._allOptionElements.forEach(applyFilter(this._query, { matching: this.filterableAttributeValue }))
38
31
  this._commitFilter(event)
39
32
  }
40
33
 
@@ -48,12 +41,17 @@ Combobox.Filtering = Base => class extends Base {
48
41
  }
49
42
  }
50
43
 
51
- async _afterTurboStreamRender(callback) {
52
- await nextFrame()
53
- callback()
44
+ get _isQueried() {
45
+ return this._query.length > 0
54
46
  }
55
47
 
56
- get _isQueried() {
57
- return this._actingCombobox.value.length > 0
48
+ // Consider +_query+ will contain the full autocompleted value
49
+ // after a certain point in the call chain.
50
+ get _query() {
51
+ return this._actingCombobox.value.trim()
52
+ }
53
+
54
+ set _query(value) {
55
+ this._actingCombobox.value = value
58
56
  }
59
57
  }
@@ -10,7 +10,7 @@ Combobox.Selection = Base => class extends Base {
10
10
 
11
11
  _connectSelection() {
12
12
  if (this.hasPrefilledDisplayValue) {
13
- this._actingCombobox.value = this.prefilledDisplayValue
13
+ this._query = this.prefilledDisplayValue
14
14
  }
15
15
  }
16
16
 
@@ -19,7 +19,7 @@ Combobox.Selection = Base => class extends Base {
19
19
 
20
20
  if (option) {
21
21
  this._markValid()
22
- this._maybeAutocompleteWith(option, { force })
22
+ this._autocompleteWith(option, { force })
23
23
  this._commitSelection(option, { selected: true })
24
24
  } else {
25
25
  this._markInvalid()
@@ -52,7 +52,7 @@ Combobox.Selection = Base => class extends Base {
52
52
 
53
53
  _selectNew() {
54
54
  this._resetOptions()
55
- this.hiddenFieldTarget.value = this._actingCombobox.value
55
+ this.hiddenFieldTarget.value = this._query
56
56
  this.hiddenFieldTarget.name = this.nameWhenNewValue
57
57
  }
58
58
 
@@ -171,7 +171,7 @@ class HotwireCombobox::Component
171
171
  if async_src && associated_object
172
172
  associated_object.to_combobox_display
173
173
  elsif hidden_field_value
174
- options.find { |option| option.value == hidden_field_value }&.content
174
+ options.find { |option| option.value == hidden_field_value }&.autocompletable_as
175
175
  end
176
176
  end
177
177
 
@@ -11,8 +11,8 @@ class HotwireCombobox::Listbox::Option
11
11
  option.try(:value) || option.id
12
12
  end
13
13
 
14
- def content
15
- option.try(:content) || option.try(:display)
14
+ def autocompletable_as
15
+ option.try(:autocompletable_as) || option.try(:display)
16
16
  end
17
17
 
18
18
  private
@@ -42,11 +42,11 @@ class HotwireCombobox::Listbox::Option
42
42
  }
43
43
  end
44
44
 
45
- def filterable_as
46
- option.try(:filterable_as) || option.try(:display)
45
+ def content
46
+ option.try(:content) || option.try(:display)
47
47
  end
48
48
 
49
- def autocompletable_as
50
- option.try(:autocompletable_as) || option.try(:display)
49
+ def filterable_as
50
+ option.try(:filterable_as) || option.try(:display)
51
51
  end
52
52
  end
@@ -1,4 +1,4 @@
1
1
  <%# locals: (for_id:, src:) -%>
2
2
 
3
3
  <%= turbo_frame_tag hw_pagination_frame_id(for_id), src: src, loading: :lazy,
4
- data: { hw_combobox_target: "paginationFrame" } %>
4
+ data: { hw_combobox_target: "endOfOptionsStream", input_type: params[:input_type] } %>
@@ -1,3 +1,3 @@
1
1
  module HotwireCombobox
2
- VERSION = "0.1.33"
2
+ VERSION = "0.1.34"
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.1.33
4
+ version: 0.1.34
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-02-27 00:00:00.000000000 Z
11
+ date: 2024-02-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails