tag_options 1.2.0 → 1.3.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 +20 -3
- data/README.md +58 -13
- data/lib/tag_options/convert_key.rb +7 -0
- data/lib/tag_options/hash.rb +8 -4
- data/lib/tag_options/hash_at.rb +24 -2
- data/lib/tag_options/resolver.rb +4 -0
- data/lib/tag_options/resolvers/default.rb +5 -1
- data/lib/tag_options/resolvers/style.rb +5 -1
- data/lib/tag_options/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5cee8f74f051ffc41909e62f0a613904ce5f342a6be1fd8d961b8f7663d66087
|
|
4
|
+
data.tar.gz: 5e8c5f2b69fe32e13330a99f4d112a412bc4e6b3a78a5233d66f11a3ad032e7c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d6613c09fbf756a9a15e3a4001e478a0c225f643c1dd3f8b58be3e63fe8c3afb0dab00bed9d8984ca75ae58b37ae4fbb4e26d0410b7d36bb0cf59f52fecbd869
|
|
7
|
+
data.tar.gz: ed905332c293482cd3610c5374bb9a7b27328cd1c245bb55c6d69fc10b4c36e7c67f6a38ca3a32ef3a0f879344c9751b9a22ae18f91f1ed21d4bf5a6b7a8cac4
|
data/CHANGELOG.md
CHANGED
|
@@ -2,20 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
## [1.
|
|
5
|
+
## [1.3.0] - 2023-03-03
|
|
6
|
+
|
|
7
|
+
- Added `at().remove!` option for removing values.
|
|
8
|
+
|
|
9
|
+
**NOTE**: If you have implemented custom resolvers, you will need to modify them
|
|
10
|
+
in order to support `remove!`. For examples, see the [built-in
|
|
11
|
+
handlers](https://github.com/wamonroe/tag_options/tree/main/lib/tag_options/resolvers)
|
|
12
|
+
for more information.
|
|
13
|
+
|
|
14
|
+
## [1.2.1] - 2023-03-02
|
|
15
|
+
|
|
16
|
+
- Fixed bug introduced when switching to
|
|
17
|
+
`ActiveSupport::HashWithIndifferentAccess` that prevented a `TagOptions::Hash`
|
|
18
|
+
from being passed to a method using double splat, e.g. `some_method
|
|
19
|
+
**options`.
|
|
20
|
+
|
|
21
|
+
## [1.2.0] - 2023-03-02
|
|
6
22
|
|
|
7
23
|
- Added `at().default!` option for setting values that are not already present.
|
|
8
24
|
- Fix for passing an array of values to `combine1` or `set!`
|
|
9
25
|
|
|
10
26
|
## [1.1.0] - 2023-03-01
|
|
11
27
|
|
|
12
|
-
- Switched to inheriting from ActiveSupport::HashWithIndifferentAccess
|
|
28
|
+
- Switched to inheriting from `ActiveSupport::HashWithIndifferentAccess`.
|
|
13
29
|
- Added before/after/around initialize callback support.
|
|
14
30
|
|
|
15
31
|
## [1.0.0] - 2022-06-14
|
|
16
32
|
|
|
17
33
|
- Rewrote and simplified TagOptions::Hash and supporting classes.
|
|
18
|
-
|
|
34
|
+
|
|
35
|
+
**BREAKING CHANGES**: Read documentation for updated usage before updating.
|
|
19
36
|
|
|
20
37
|
## [0.9.3] - 2021-11-11
|
|
21
38
|
|
data/README.md
CHANGED
|
@@ -42,6 +42,7 @@ Would render:
|
|
|
42
42
|
- [combine!](#combine)
|
|
43
43
|
- [set!](#set)
|
|
44
44
|
- [default!](#default)
|
|
45
|
+
- [remove!](#remove)
|
|
45
46
|
- [Conditional Usage](#conditional-usage)
|
|
46
47
|
- [Custom Property Resolvers](#custom-property-resolvers)
|
|
47
48
|
- [Development](#development)
|
|
@@ -72,11 +73,14 @@ TagOptions::Hash.new
|
|
|
72
73
|
|
|
73
74
|
hash = {class: "flex"}
|
|
74
75
|
TagOptions::Hash.new(hash)
|
|
75
|
-
=> {
|
|
76
|
+
=> {:class=>"flex"}
|
|
76
77
|
```
|
|
77
78
|
|
|
78
79
|
`TagOptions::Hash` inherits from `ActiveSupport::HashWithIndifferentAccess`,
|
|
79
80
|
implementing a hash where keys `:foo` and `"foo"` are considered to be the same.
|
|
81
|
+
It differs from `ActiveSupport::HashWithIndifferentAccess`, however, by storing
|
|
82
|
+
the keys as symbols instead of strings to make it easier to pass the hash as
|
|
83
|
+
an method argument using double splat, e.g. `some_method **options`.
|
|
80
84
|
|
|
81
85
|
### combine!
|
|
82
86
|
|
|
@@ -86,7 +90,7 @@ Combine HTML attributes with an existing `TagOptions::Hash` by chaining `at` and
|
|
|
86
90
|
```ruby
|
|
87
91
|
options = TagOptions::Hash.new(class: "flex")
|
|
88
92
|
options.at(:class).combine!("mt-1")
|
|
89
|
-
=> {
|
|
93
|
+
=> {:class=>"flex mt-1"}
|
|
90
94
|
```
|
|
91
95
|
|
|
92
96
|
Values can also be specified as arrays.
|
|
@@ -94,7 +98,7 @@ Values can also be specified as arrays.
|
|
|
94
98
|
```ruby
|
|
95
99
|
options = TagOptions::Hash.new(class: "flex")
|
|
96
100
|
options.at(:class).combine!(["mt-1", "mx-2"])
|
|
97
|
-
=> {
|
|
101
|
+
=> {:class=>"flex mt-1 mx-2"}
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
HTML attributes are only added if they don't already exist.
|
|
@@ -102,7 +106,7 @@ HTML attributes are only added if they don't already exist.
|
|
|
102
106
|
```ruby
|
|
103
107
|
options = TagOptions::Hash.new(class: "flex")
|
|
104
108
|
options.at(:class).combine!("flex flex-col")
|
|
105
|
-
=> {
|
|
109
|
+
=> {:class=>"flex flex-col"}
|
|
106
110
|
```
|
|
107
111
|
|
|
108
112
|
You can also combine values on nested hashes.
|
|
@@ -110,7 +114,7 @@ You can also combine values on nested hashes.
|
|
|
110
114
|
```ruby
|
|
111
115
|
options = TagOptions::Hash.new(class: "flex", data: {controller: "dropdown"})
|
|
112
116
|
options.at(:data, :controller).combine!("toggle")
|
|
113
|
-
=> {
|
|
117
|
+
=> {:class=>"flex", :data=>{:controller=>"dropdown toggle"}
|
|
114
118
|
```
|
|
115
119
|
|
|
116
120
|
If a nested hash doesn't already exist it will be automatically added.
|
|
@@ -118,7 +122,7 @@ If a nested hash doesn't already exist it will be automatically added.
|
|
|
118
122
|
```ruby
|
|
119
123
|
options = TagOptions::Hash.new(class: "flex")
|
|
120
124
|
options.at(:data, :controller).combine!("dropdown")
|
|
121
|
-
=> {
|
|
125
|
+
=> {:class=>"flex", :data=>{:controller=>"dropdown"}
|
|
122
126
|
```
|
|
123
127
|
|
|
124
128
|
### set!
|
|
@@ -130,7 +134,7 @@ existing values.
|
|
|
130
134
|
```ruby
|
|
131
135
|
options = TagOptions::Hash.new(class: "flex")
|
|
132
136
|
options.at(:class).set!("block")
|
|
133
|
-
=> {
|
|
137
|
+
=> {:class=>"block"}
|
|
134
138
|
```
|
|
135
139
|
|
|
136
140
|
### default!
|
|
@@ -143,20 +147,61 @@ set the specified values if the value is not already specified.
|
|
|
143
147
|
options = TagOptions::Hash.new(class: "flex")
|
|
144
148
|
options.at(:class).default!("block")
|
|
145
149
|
options.at(:role).default!("alert")
|
|
146
|
-
=> {
|
|
150
|
+
=> {:class=>"flex", :role=>"alert"}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### remove!
|
|
154
|
+
|
|
155
|
+
Remove HTML attributes from an existing `TagOptions::Hash` by chaining `at` and
|
|
156
|
+
`remove!`.
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
options = TagOptions::Hash.new(class: "flex ml-1 mr-1")
|
|
160
|
+
options.at(:class).remove!("mr-1")
|
|
161
|
+
=> {:class=>"flex ml-1"}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
In addition to string values, you can also pass regular expression to `remove!`.
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
options = TagOptions::Hash.new(class: "flex ml-1 mr-2")
|
|
168
|
+
options.at(:class).remove!(/m.-\d/)
|
|
169
|
+
=> {:class=>"flex"}
|
|
147
170
|
```
|
|
148
171
|
|
|
149
172
|
## Conditional Usage
|
|
150
173
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
unconditionally and key/value pairs have their key
|
|
174
|
+
The `combine!`, `set!`, `default!`, and `remove!` methods allow for values to be
|
|
175
|
+
conditionally resolved using an argument array. Where the values are passed
|
|
176
|
+
unconditionally and key/value pairs have their key passed _IF_ the value is
|
|
177
|
+
true.
|
|
154
178
|
|
|
155
179
|
```ruby
|
|
156
180
|
# assuming `centered?` returns `true`
|
|
157
181
|
options = TagOptions::Hash.new(class: "flex")
|
|
158
182
|
options.at(:class).combine!("mt-1", "mx-auto": centered?, "mx-2": !centered?)
|
|
159
|
-
=> {
|
|
183
|
+
=> {:class=>"flex mt-1 mx-auto"}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```ruby
|
|
187
|
+
# assuming `centered?` returns `true`
|
|
188
|
+
options = TagOptions::Hash.new(class: "flex")
|
|
189
|
+
options.at(:class).set!("block", "mx-auto": centered?, "mx-2": !centered?)
|
|
190
|
+
=> {:class=>"block mx-auto"}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
# assuming `centered?` returns `true`
|
|
195
|
+
options = TagOptions::Hash.new(role: "alert")
|
|
196
|
+
options.at(:class).default!("flex", "mx-auto": centered?, "mx-2": !centered?)
|
|
197
|
+
=> {:role=>"alert", :class=>"flex mx-auto"}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```ruby
|
|
201
|
+
# assuming `centered?` returns `true`
|
|
202
|
+
options = TagOptions::Hash.new(class: "flex mx-auto mx-2")
|
|
203
|
+
options.at(:class).remove!("mt-1", "mx-auto": centered?, "mx-2": !centered?)
|
|
204
|
+
=> {:class=>"flex mx-2"}
|
|
160
205
|
```
|
|
161
206
|
|
|
162
207
|
## Custom Property Resolvers
|
|
@@ -181,7 +226,7 @@ pass `as: :style` to `at`.
|
|
|
181
226
|
```ruby
|
|
182
227
|
options = TagOptions::Hash.new(style: "display: block; margin-left: 0;")
|
|
183
228
|
options.at(:style, as: :style).combine!("display: flex; margin-right: 0;")
|
|
184
|
-
=> {
|
|
229
|
+
=> {:style=>"display: flex; margin-left: 0; margin-right: 0;"}
|
|
185
230
|
```
|
|
186
231
|
|
|
187
232
|
A `TagOptions::Resolver` class is available if you wish to implement your own
|
data/lib/tag_options/hash.rb
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
require "active_support/callbacks"
|
|
2
2
|
require "active_support/core_ext/hash/indifferent_access"
|
|
3
|
+
require "tag_options/convert_key"
|
|
3
4
|
require "tag_options/hash_at"
|
|
4
5
|
require "tag_options/errors/not_hash_error"
|
|
5
6
|
|
|
6
7
|
module TagOptions
|
|
7
8
|
class Hash < ActiveSupport::HashWithIndifferentAccess
|
|
8
9
|
include ActiveSupport::Callbacks
|
|
10
|
+
include ConvertKey
|
|
11
|
+
|
|
9
12
|
define_callbacks :initialize
|
|
10
13
|
|
|
11
14
|
def initialize(hash = {})
|
|
12
15
|
run_callbacks :initialize do
|
|
13
16
|
hash.each do |key, value|
|
|
14
|
-
self[key] = value.is_a?(::Hash) ? self.class.new(value) : value
|
|
17
|
+
self[convert_key(key)] = value.is_a?(::Hash) ? self.class.new(value) : value
|
|
15
18
|
end
|
|
16
19
|
end
|
|
17
20
|
end
|
|
@@ -21,15 +24,16 @@ module TagOptions
|
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def dig(*keys)
|
|
24
|
-
keys.
|
|
27
|
+
keys = keys.map { |key| convert_key(key) }
|
|
28
|
+
keys.size.zero? ? self : super(*keys)
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
def populate!(*keys)
|
|
28
32
|
populated_keys = []
|
|
29
33
|
data = self
|
|
30
34
|
keys.each do |key|
|
|
31
|
-
data[key] ||= self.class.new
|
|
32
|
-
data = data[key]
|
|
35
|
+
data[convert_key(key)] ||= self.class.new
|
|
36
|
+
data = data[convert_key(key)]
|
|
33
37
|
unless data.is_a?(self.class)
|
|
34
38
|
raise TagOptions::Errors::NotHashError.new(populated_keys, type: data.class)
|
|
35
39
|
end
|
data/lib/tag_options/hash_at.rb
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
require "tag_options/configuration"
|
|
2
|
+
require "tag_options/convert_key"
|
|
2
3
|
|
|
3
4
|
module TagOptions
|
|
4
5
|
class HashAt
|
|
6
|
+
include ConvertKey
|
|
7
|
+
|
|
5
8
|
def initialize(opt_hash:, keys:, as:)
|
|
6
9
|
@opt_hash = opt_hash
|
|
7
|
-
@keys = keys[..-2]
|
|
8
|
-
@value_key = keys[-1]
|
|
10
|
+
@keys = keys[..-2].map { |key| convert_key(key) }
|
|
11
|
+
@value_key = convert_key(keys[-1])
|
|
9
12
|
@resolver = TagOptions.configuration.resolver(as)
|
|
10
13
|
end
|
|
11
14
|
|
|
@@ -25,8 +28,27 @@ module TagOptions
|
|
|
25
28
|
set_value! @resolver.call(*values, **conditions)
|
|
26
29
|
end
|
|
27
30
|
|
|
31
|
+
def remove!(*values, **conditions)
|
|
32
|
+
@opt_hash.populate!(*@keys)
|
|
33
|
+
regex_values, values = values.flatten.partition { |v| v.is_a?(Regexp) }
|
|
34
|
+
remove_values!(*regex_values, *@resolver.values(*values, **conditions))
|
|
35
|
+
end
|
|
36
|
+
|
|
28
37
|
private
|
|
29
38
|
|
|
39
|
+
def remove_values!(*values_to_remove)
|
|
40
|
+
values = @resolver.values(@opt_hash.dig(*@keys)[@value_key])
|
|
41
|
+
values_to_remove.each do |value|
|
|
42
|
+
if value.is_a?(Regexp)
|
|
43
|
+
values.reject! { |current_value| value.match?(current_value) }
|
|
44
|
+
else
|
|
45
|
+
values.reject! { |current_value| value == current_value }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
@opt_hash.dig(*@keys)[@value_key] = @resolver.call(*values)
|
|
49
|
+
@opt_hash
|
|
50
|
+
end
|
|
51
|
+
|
|
30
52
|
def set_default!(value)
|
|
31
53
|
root = @opt_hash.dig(*@keys)
|
|
32
54
|
root[@value_key] = value unless root.key?(@value_key)
|
data/lib/tag_options/resolver.rb
CHANGED
|
@@ -4,7 +4,11 @@ module TagOptions
|
|
|
4
4
|
module Resolvers
|
|
5
5
|
class Default < Resolver
|
|
6
6
|
def call
|
|
7
|
-
|
|
7
|
+
values.join(" ")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def values
|
|
11
|
+
@values.map { |v| v.to_s.split }.flatten.compact.uniq
|
|
8
12
|
end
|
|
9
13
|
end
|
|
10
14
|
end
|
data/lib/tag_options/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tag_options
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Monroe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-03-
|
|
11
|
+
date: 2023-03-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -51,6 +51,7 @@ files:
|
|
|
51
51
|
- Rakefile
|
|
52
52
|
- lib/tag_options.rb
|
|
53
53
|
- lib/tag_options/configuration.rb
|
|
54
|
+
- lib/tag_options/convert_key.rb
|
|
54
55
|
- lib/tag_options/error.rb
|
|
55
56
|
- lib/tag_options/errors/not_hash_error.rb
|
|
56
57
|
- lib/tag_options/errors/resolver_error.rb
|