stimulus_table_filter 0.1.0 → 0.2.0
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 +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +2 -2
- data/README.md +35 -11
- data/app/assets/javascripts/stimulus_table_filter/table_filter_controller.js +1 -0
- data/lib/stimulus_table_filter/version.rb +1 -1
- data/lib/stimulus_table_filter/view_helper/container.rb +4 -3
- data/lib/stimulus_table_filter/view_helper/controls.rb +20 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 495418a93784ca089dccd7fca9636a3bcc89a7e2f42599fc0cb9c6676be34ef7
|
|
4
|
+
data.tar.gz: c7486ef81d34dc5cd0d09ff3f2bd5047105f2810c25a296b960f1cdcaacddba1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9f256274e5dc8b69d2db008c7547781987d20dd67a0825f0c9e89af99c6b4b715bf6519ba80017073fe35cd6662e8776177ea9f0abd7ff78b8550ffc7e103f4
|
|
7
|
+
data.tar.gz: b61979d520487ce847e45c00d7d66c66c91adb8eaebb54a9a5742947825e666fda4c947fede3bada960eaf1546f4e584d65cae21f07b75c867cfb41310bf4f4b
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## [0.2.0] - 2026-10-15
|
|
7
|
+
|
|
8
|
+
- Add `table_filter_bar_tag`: a search input and optional filter buttons in one toolbar. It
|
|
9
|
+
raises `StimulusTableFilter::Error` when `filters:` is given without `dimension:`
|
|
10
|
+
|
|
11
|
+
## [0.1.1] - 2026-08-31
|
|
12
|
+
|
|
13
|
+
- `table_filter_container_tag` accepts a `search:` option and emits
|
|
14
|
+
`data-table-filter-search-value`, matching the documented data-attribute contract
|
|
15
|
+
- README: document that `table_filter_footer_tag` wraps its content in a footer element, a
|
|
16
|
+
`<tr>` and a `<td>`; correct the URL-state and programmatic-API behavior notes
|
|
17
|
+
|
|
6
18
|
## [0.1.0] - 2026-08-25
|
|
7
19
|
|
|
8
20
|
Initial release.
|
|
@@ -13,4 +25,5 @@ Initial release.
|
|
|
13
25
|
- RSpec support: shared examples plus `have_data` / `have_data_target` matchers
|
|
14
26
|
- CI: RuboCop, RSpec and JavaScript tests across Ruby 3.2–3.4 and Rails 7.0–8.1
|
|
15
27
|
|
|
28
|
+
[0.1.1]: https://github.com/icoluccio/stimulus-table-filter/releases/tag/v0.1.1
|
|
16
29
|
[0.1.0]: https://github.com/icoluccio/stimulus-table-filter/releases/tag/v0.1.0
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
stimulus_table_filter (0.
|
|
4
|
+
stimulus_table_filter (0.2.0)
|
|
5
5
|
railties (>= 7.0, < 9)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -285,7 +285,7 @@ CHECKSUMS
|
|
|
285
285
|
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
|
|
286
286
|
sexp_processor (4.17.5) sha256=ae2b48ba98353d5d465ce8759836b7a05f2e12c5879fcd14d7815b026de32f0e
|
|
287
287
|
simplecov (1.1.1) sha256=25825ef13f0b2e74694d769817dad6ab8e90131dabdaa666e522fea105521e78
|
|
288
|
-
stimulus_table_filter (0.
|
|
288
|
+
stimulus_table_filter (0.2.0)
|
|
289
289
|
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
|
|
290
290
|
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
|
|
291
291
|
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
data/README.md
CHANGED
|
@@ -110,13 +110,8 @@ A complete filterable table in one view partial:
|
|
|
110
110
|
|
|
111
111
|
```erb
|
|
112
112
|
<%= table_filter_container_tag do %>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<%= table_filter_search_tag(placeholder: "Search users…") %>
|
|
116
|
-
<%= table_filter_filter_btn_tag("all", "All", dimension: "status") %>
|
|
117
|
-
<%= table_filter_filter_btn_tag("active", "Active", dimension: "status") %>
|
|
118
|
-
<%= table_filter_filter_btn_tag("archived", "Archived", dimension: "status") %>
|
|
119
|
-
</div>
|
|
113
|
+
<%= table_filter_bar_tag(placeholder: "Search users…", dimension: "status",
|
|
114
|
+
filters: { "all" => "All", "active" => "Active", "archived" => "Archived" }) %>
|
|
120
115
|
|
|
121
116
|
<table>
|
|
122
117
|
<thead>
|
|
@@ -176,6 +171,7 @@ the controller reads on connect.
|
|
|
176
171
|
| `page_size:` | `nil` | Rows per page (omit or `0` to disable pagination) |
|
|
177
172
|
| `url_key:` | `nil` | URL param prefix (default `tf`); set per table to namespace multiple tables |
|
|
178
173
|
| `debounce_ms:` | `nil` | Search debounce in ms (default `0` = immediate) |
|
|
174
|
+
| `search:` | `nil` | Initial search text (emits `data-table-filter-search-value`) |
|
|
179
175
|
| `tag:` | `:div` | Wrapping HTML element |
|
|
180
176
|
|
|
181
177
|
Every helper accepts `**opts` and passes them through to the underlying tag.
|
|
@@ -224,6 +220,28 @@ filters. Omit `filters:` and the filter helpers entirely for a search-and-sort-o
|
|
|
224
220
|
Filters rows by matching `data-name`, or `data-searchable` when present. Case-insensitive
|
|
225
221
|
substring match.
|
|
226
222
|
|
|
223
|
+
### Toolbar
|
|
224
|
+
|
|
225
|
+
`table_filter_bar_tag` renders the search input and, when `filters:` is given, a group of filter
|
|
226
|
+
buttons inside one `<div>`:
|
|
227
|
+
|
|
228
|
+
```erb
|
|
229
|
+
<%= table_filter_bar_tag(placeholder: "Search users…", dimension: "status",
|
|
230
|
+
filters: { "all" => "All", "active" => "Active" },
|
|
231
|
+
class: "flex gap-2", search: { class: "input" }, group: { class: "join" }, button: { class: "btn" }) %>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
| Option | Applies to |
|
|
235
|
+
| --- | --- |
|
|
236
|
+
| `placeholder:` | The search input |
|
|
237
|
+
| `filters:` | `{ value => label }`; one button per entry. Omit it for a search-only bar. No group renders |
|
|
238
|
+
| `dimension:` | The dimension every button acts on. **Required** with `filters:`. Without it the helper raises `StimulusTableFilter::Error` |
|
|
239
|
+
| `search:`, `group:`, `button:` | Extra attributes (`class:`, `data:`, ...) for the input, the button group `<div>` and each button |
|
|
240
|
+
| any other option | The outer `<div>` |
|
|
241
|
+
|
|
242
|
+
It wraps `table_filter_search_tag` and `table_filter_filter_btn_tag`. Call those directly when
|
|
243
|
+
you need a different layout.
|
|
244
|
+
|
|
227
245
|
### Filter buttons
|
|
228
246
|
|
|
229
247
|
```erb
|
|
@@ -315,6 +333,9 @@ The default footer shows how many rows match the current filter and search, out
|
|
|
315
333
|
<!-- renders: <span>12</span> of <span>87</span> -->
|
|
316
334
|
```
|
|
317
335
|
|
|
336
|
+
The helper wraps the content in the footer element (a `<tfoot>` by default), a `<tr>`, and a
|
|
337
|
+
`<td>`; `colspan:` applies to that cell and `tag:` replaces only the outer element.
|
|
338
|
+
|
|
318
339
|
Or build your own footer. The block receives the match-count and total-count spans:
|
|
319
340
|
|
|
320
341
|
```erb
|
|
@@ -399,11 +420,14 @@ Behavior notes:
|
|
|
399
420
|
- **Footer stats**: the match count covers every row that passes the active filters and search,
|
|
400
421
|
across all pages. Count tags populate with the number of matching rows whose dimension value
|
|
401
422
|
equals the tag's value.
|
|
402
|
-
- **URL state**:
|
|
403
|
-
`URLSearchParams`
|
|
404
|
-
|
|
423
|
+
- **URL state**: the controller syncs filter dimensions, sort, direction, page and search to
|
|
424
|
+
`URLSearchParams` when the user changes them (dimensions as `tf_filter_{dimension}` params)
|
|
425
|
+
and restores them on connect without rewriting the URL. Namespace multiple tables with
|
|
426
|
+
`data-table-filter-url-key-value`.
|
|
405
427
|
- **Event handling**: the controller delegates all events itself; individual elements
|
|
406
|
-
need no `data-action`.
|
|
428
|
+
need no `data-action`. Call `search()` programmatically. For filters and sort, set the
|
|
429
|
+
Stimulus values and refresh, e.g.
|
|
430
|
+
`controller.filterDimensionsValue = { status: 'active' }; controller.refresh()`.
|
|
407
431
|
|
|
408
432
|
### RSpec shared examples
|
|
409
433
|
|
|
@@ -38,6 +38,7 @@ export default class extends Controller {
|
|
|
38
38
|
|
|
39
39
|
connect() {
|
|
40
40
|
this.#readUrlState()
|
|
41
|
+
if (this.hasSearchTarget && this.searchValue) this.searchTarget.value = this.searchValue
|
|
41
42
|
this.element.addEventListener("click", this.#onClick)
|
|
42
43
|
this.element.addEventListener("input", this.#onInput)
|
|
43
44
|
this.element.addEventListener("change", this.#onChange)
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
module StimulusTableFilter
|
|
4
4
|
module ViewHelper
|
|
5
5
|
def table_filter_container_tag(sort: 'name', dir: 'asc', page: nil, page_size: nil, url_key: nil,
|
|
6
|
-
debounce_ms: nil, tag: :div, **opts, &)
|
|
6
|
+
debounce_ms: nil, search: nil, tag: :div, **opts, &)
|
|
7
7
|
data = container_data(sort:, dir:, page:, page_size:, url_key:,
|
|
8
|
-
debounce_ms:).merge(opts.delete(:data) || {})
|
|
8
|
+
debounce_ms:, search:).merge(opts.delete(:data) || {})
|
|
9
9
|
content_tag(tag, data: data, **opts, &)
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -17,11 +17,12 @@ module StimulusTableFilter
|
|
|
17
17
|
base
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def container_data(sort:, dir:, page: nil, page_size: nil, url_key: nil, debounce_ms: nil)
|
|
20
|
+
def container_data(sort:, dir:, page: nil, page_size: nil, url_key: nil, debounce_ms: nil, search: nil)
|
|
21
21
|
base = base_container_data(sort:, dir:, page:)
|
|
22
22
|
base = base.merge(table_filter_page_size_value: page_size.to_s) if page_size
|
|
23
23
|
base = base.merge(table_filter_url_key_value: url_key.to_s) if url_key
|
|
24
24
|
base = base.merge(table_filter_debounce_ms_value: debounce_ms.to_s) if debounce_ms
|
|
25
|
+
base = base.merge(table_filter_search_value: search.to_s) if search
|
|
25
26
|
base
|
|
26
27
|
end
|
|
27
28
|
end
|
|
@@ -4,6 +4,14 @@ module StimulusTableFilter
|
|
|
4
4
|
module ViewHelper
|
|
5
5
|
def table_filter_search_tag(**opts) = tag.input(type: 'search', data: target_data('search', opts), **opts)
|
|
6
6
|
|
|
7
|
+
# Raises StimulusTableFilter::Error if +filters+ is given without +dimension+.
|
|
8
|
+
def table_filter_bar_tag(placeholder: nil, filters: {}, dimension: nil, search: {}, group: {}, button: {}, **opts)
|
|
9
|
+
content_tag(:div, **opts) do
|
|
10
|
+
safe_join([table_filter_search_tag(placeholder: placeholder, **search),
|
|
11
|
+
table_filter_button_group(filters, dimension, group, button)])
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
7
15
|
def table_filter_filter_btn_tag(value, label, dimension: nil, **opts)
|
|
8
16
|
data = with_data({ filter_btn: value }, opts)
|
|
9
17
|
data[:filter_dimension] = dimension if dimension
|
|
@@ -31,6 +39,18 @@ module StimulusTableFilter
|
|
|
31
39
|
|
|
32
40
|
private
|
|
33
41
|
|
|
42
|
+
def table_filter_button_group(filters, dimension, group, button)
|
|
43
|
+
return if filters.empty?
|
|
44
|
+
|
|
45
|
+
content_tag(:div, table_filter_buttons(filters, dimension, button), **group)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def table_filter_buttons(filters, dimension, button)
|
|
49
|
+
raise Error, 'table_filter_bar_tag requires dimension: when filters are given' unless dimension
|
|
50
|
+
|
|
51
|
+
safe_join(filters.map { |value, label| table_filter_filter_btn_tag(value, label, dimension:, **button) })
|
|
52
|
+
end
|
|
53
|
+
|
|
34
54
|
def option_tag(pair) = content_tag(:option, pair.first, value: pair.last)
|
|
35
55
|
def render_options(pairs) = safe_join(pairs.map(&method(:option_tag)))
|
|
36
56
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stimulus_table_filter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- icoluccio
|
|
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
102
|
version: '0'
|
|
103
103
|
requirements: []
|
|
104
|
-
rubygems_version: 3.6.
|
|
104
|
+
rubygems_version: 3.6.7
|
|
105
105
|
specification_version: 4
|
|
106
106
|
summary: Client-side table filtering, sorting and search for Rails
|
|
107
107
|
test_files: []
|