hotwire_combobox 0.1.6 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06d497472d7966424ceea6dc655bf8baf2bfa7b2232ab587bb1ca6221f1b8e13
4
- data.tar.gz: 994345e54975287e4958e917d8ff687851e6628604249c5ec59e2bcf9a858fb2
3
+ metadata.gz: 9cb2abe7ffd7dc81c39b774fb0028f0f9650182978735f3d21a3d375a32a948e
4
+ data.tar.gz: a038bd3ce8baff5a47e281be380cc0c4c0b77433cab3161174958a0f135fab08
5
5
  SHA512:
6
- metadata.gz: b3bd3a8d9266f43a542641f762ae059d2f8cc2a5c3d98f14b8a853bc5173fd5b382482fa89c0ff103df7e3e24fbf06a6aad5fccffe4d01bd3194959114610742
7
- data.tar.gz: aa29ec37fa9fd51d640622686a91f6e2bf31c6c9df6a1618d88d540dcea3c1f6e5033379bf0397726904a34a19927bb1b5e9b016d797e7e861d993229e79d171
6
+ metadata.gz: 52b14433be746e89f6e0612f42d3a84ed323ebb2931a93d535b90bb9eb1fbde555ea3bf0a3496774b9eb91c30ba0035576e6c3fab7da69e97e7228e927767e69
7
+ data.tar.gz: '09662cb44deb6854dca5d7a6919ae6170dff3ebcbbae9cab7ea7b1b368ec85e0db82f823a3471886cb55b9e4a44da6bd7e141bdc0e5948266b118ed96b2873bc'
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
- # Hotwire Combobox
2
- Short description and motivation.
1
+ # HotwireCombobox
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ A combobox implementation for Ruby on Rails apps running on Hotwire.
4
+
5
+ > [!WARNING]
6
+ > This gem is pre-release software. It's not ready for production use yet and the API is subject to change.
6
7
 
7
8
  ## Installation
9
+
8
10
  Add this line to your application's Gemfile:
9
11
 
10
12
  ```ruby
@@ -16,38 +18,107 @@ And then execute:
16
18
  $ bundle
17
19
  ```
18
20
 
19
- Or install it yourself as:
20
- ```bash
21
- $ gem install hotwire_combobox
22
- ```
21
+ ## Output
23
22
 
24
- ## Contributing
23
+ This is the stripped-down output of a combobox generated with HotwireCombobox. Understanding it will be helpful in getting the most out of this library.
25
24
 
26
- ### Setup
27
- ```bash
28
- $ bin/setup
29
- ```
25
+ ```html
26
+ <fieldset class="hw-combobox">
27
+ <input type="hidden" name="provided_name">
30
28
 
31
- ### Running the tests
32
- ```bash
33
- $ bundle exec rake app:test
29
+ <input type="text" role="combobox">
30
+
31
+ <ul role="listbox">
32
+ <li role="option">Provided Option 1 Content</li>
33
+ <li role="option">Provided Option 2 Content</li>
34
+ <!-- ... -->
35
+ </ul>
36
+ </fieldset>
34
37
  ```
35
38
 
36
- ```bash
37
- $ bundle exec rake app:test:system
39
+ The `<ul role="listbox">` element is what gets shown when the combobox is open.
40
+
41
+ The library uses stimulus to add interactivity to the combobox and sync the input element's value with the hidden input element.
42
+
43
+ The hidden input's value is what ultimately gets sent to the server when submitting a form containing the combobox.
44
+
45
+ ## Usage
46
+
47
+ ### Options
48
+
49
+ Options are what you see when you open the combobox.
50
+
51
+ The `options` argument takes an array of any objects which respond to:
52
+
53
+ | Method | Description |
54
+ |--------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
55
+ | id | Used as the option element's `id` attribute. Only required if `value` is not provided. |
56
+ | value | Used to populate the input element's `value` attribute. Falls back to calling `id` on the object if not provided. |
57
+ | content | **Supports HTML** <br> Used as the option element's content. Falls back to calling `display` on the object if not provided. |
58
+ | filterable_as | Used to filter down the options when the user types into the input element. Falls back to calling `display` on the object if not provided. |
59
+ | autocompletable_as | Used to autocomplete the input element when the user types into it. Falls back to calling `display` on the object if not provided. |
60
+ | display | Used as a short-hand for other attributes. See the rest of the list for details. |
61
+
62
+ > [!NOTE]
63
+ > The `id` attribute is required only if `value` is not provided.
64
+
65
+ You can use the `combobox_options` helper to create an array of option objects which respond to the above methods:
66
+
67
+ ```ruby
68
+ combobox_options [
69
+ { value: "AL", display: "Alabama" },
70
+ { value: "AK", display: "Alaska" },
71
+ { value: "AZ", display: "Arizona" },
72
+ # ...
73
+ ]
38
74
  ```
39
75
 
40
- ### Running the dummy app
41
- ```bash
42
- $ bin/rails s
76
+ ### Styling
77
+
78
+ The combobox is completely unstyled by default. You can use the following CSS selectors to style the combobox:
79
+
80
+ * `.hw-combobox` targets the `<fieldset>` element used to wrap the whole component.
81
+ * `.hw-combobox [role="combobox"]` targets the input element.
82
+ * `.hw-combobox [role="listbox"]` targets the listbox which encloses all option elements.
83
+ * `.hw-combobox [role="option"]` targets each option element inside the listbox.
84
+
85
+ Additionally, you can pass the following [Stimulus class values](https://stimulus.hotwired.dev/reference/css-classes) to `combobox_tag`:
86
+
87
+ * `data-hw-combobox-selected-class`: The class to apply to the selected option while shown inside an open listbox.
88
+ * `data-hw-combobox-invalid-class`: The class to apply to the input element when the current value is invalid.
89
+
90
+ ### Validity
91
+
92
+ The hidden input can't have a value that's not in the list of options.
93
+
94
+ If a nonexistent value is typed into the combobox, the value of the hidden input will be set empty.
95
+
96
+ The only way a value can be marked as invalid is if the field is required and empty after having interacted with the combobox.
97
+
98
+ The library will mark the element as invalid but this won't be noticeable in the UI unless you specify styles for the invalid state. See the [Styling](#styling) section for details.
99
+
100
+ > [!CAUTION]
101
+ > Bad actors can still submit invalid values to the server. You should always validate the input on the server side.
102
+
103
+ ### Naming Conflicts
104
+
105
+ If your application has naming conflicts with this gem, the following config will turn:
106
+
107
+ * `#combobox_tag` into `#hw_combobox_tag`
108
+ * `#combobox_options` into `#hw_combobox_options`
109
+
110
+ ```ruby
111
+ # config/initializers/hotwire_combobox.rb
112
+
113
+ HotwireCombobox.setup do |config|
114
+ config.bypass_convenience_methods = true
115
+ end
43
116
  ```
44
117
 
45
- ### Releasing
118
+ ## Contributing
46
119
 
47
- 1. Bump the version in `lib/hotwire_combobox/version.rb` (e.g. `VERSION = "0.1.0"`)
48
- 2. Bump the version in `Gemfile.lock` (e.g. `hotwire_combobox (0.1.0)`)
49
- 3. Commit the change (e.g. `git commit -am "Bump to 0.1.0"`)
50
- 4. Run `bundle exec rake release`
120
+ Please read [CONTRIBUTING.md](./CONTRIBUTING.md).
51
121
 
52
122
  ## License
123
+
53
124
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,5 +1,9 @@
1
1
  module HotwireCombobox
2
2
  module Helper
3
+ def hw_combobox_options(options)
4
+ options.map { |option| hw_combobox_option(**option) }
5
+ end
6
+
3
7
  def hw_combobox_tag(name, value = nil, form: nil, options: [], data: {}, input: {}, **attrs)
4
8
  value_field_attrs = {}.tap do |h|
5
9
  h[:id] = default_hw_combobox_value_field_id attrs, form, name
@@ -20,11 +24,36 @@ module HotwireCombobox
20
24
  parent_data: default_hw_combobox_parent_data(attrs, data)
21
25
  end
22
26
 
23
- def value_for_hw_listbox_option(option)
27
+ unless HotwireCombobox.bypass_convenience_methods?
28
+ alias_method :combobox_options, :hw_combobox_options
29
+ alias_method :combobox_tag, :hw_combobox_tag
30
+ end
31
+
32
+ def hw_listbox_option_id(option)
33
+ option.try(:id)
34
+ end
35
+
36
+ def hw_listbox_option_value(option)
24
37
  option.try(:value) || option.id
25
38
  end
26
39
 
40
+ def hw_listbox_option_content(option)
41
+ option.try(:content) || option.try(:display)
42
+ end
43
+
44
+ def hw_listbox_option_filterable_as(option)
45
+ option.try(:filterable_as) || option.try(:display)
46
+ end
47
+
48
+ def hw_listbox_option_autocompletable_as(option)
49
+ option.try(:autocompletable_as) || option.try(:display)
50
+ end
51
+
27
52
  private
53
+ def hw_combobox_option(...)
54
+ HotwireCombobox::Option.new(...)
55
+ end
56
+
28
57
  def default_hw_combobox_value_field_id(attrs, form, name)
29
58
  attrs.delete(:id) || form&.field_id(name)
30
59
  end
@@ -7,13 +7,15 @@
7
7
  <%= tag.ul id: listbox_id, hidden: "", role: :listbox,
8
8
  data: { "hw-combobox-target": "listbox" } do |ul| %>
9
9
  <% options.each do |option| %>
10
- <%= tag.li option.content, id: option.try(:id),
11
- role: :option, style: "cursor: pointer;",
10
+ <%= tag.li hw_listbox_option_content(option),
11
+ id: hw_listbox_option_id(option),
12
+ role: :option,
13
+ style: "cursor: pointer;",
12
14
  data: {
13
15
  "action": "click->hw-combobox#selectOption",
14
- "filterable-as": option.try(:filterable_as),
15
- "autocompletable-as": option.try(:autocompletable_as),
16
- "value": value_for_hw_listbox_option(option) } %>
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) } %>
17
19
  <% end %>
18
20
  <% end %>
19
21
  <% end %>
@@ -1,3 +1,3 @@
1
1
  module HotwireCombobox
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.8"
3
3
  end
@@ -2,5 +2,18 @@ require "hotwire_combobox/version"
2
2
  require "hotwire_combobox/engine"
3
3
 
4
4
  module HotwireCombobox
5
- Option = Struct.new(:id, :value, :content, :filterable_as, :autocompletable_as)
5
+ Option = Struct.new(:id, :value, :display, :content, :filterable_as, :autocompletable_as)
6
+
7
+ mattr_accessor :bypass_convenience_methods
8
+ @@bypass_convenience_methods = false
9
+
10
+ class << self
11
+ def setup
12
+ yield self
13
+ end
14
+
15
+ def bypass_convenience_methods?
16
+ bypass_convenience_methods
17
+ end
18
+ end
6
19
  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.6
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jose Farias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-10 00:00:00.000000000 Z
11
+ date: 2023-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails