hotwire_combobox 0.1.6 → 0.1.8

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: 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