html_attrs 1.0.0 → 1.1.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/Gemfile.lock +1 -2
- data/README.md +39 -10
- data/lib/html_attrs.rb +63 -19
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e275871a3e81adcaa8d6856c397adab49166f15b6f4357ae3e3606864b1559c
|
4
|
+
data.tar.gz: 73891eb35e4a0372a31c588f016ec14b1f7a834cccebea57718503b33a63eb18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11166749fdd6b6680acb6a07f8743ca106c76679adde0804339b2e20ed57e1896d5fa6823f25aed5b1266447feaa2b7d0abe65fadae30e00fc49e07eb6aefd90
|
7
|
+
data.tar.gz: cdc3bf3931938151fa88fcb7c1a873d81776e779ff350c7643553b9e53e88a5c1382048fb15e85cad2e85628f2cfb6d523aa5200c5920fa72bd7c01ef47c7491
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -16,7 +16,7 @@ $ bundle add html_attrs
|
|
16
16
|
```ruby
|
17
17
|
html_attrs = {
|
18
18
|
class: 'bg-primary-500', data: { controller: 'popover', action: 'click->popover#toggle' }
|
19
|
-
}
|
19
|
+
}
|
20
20
|
|
21
21
|
html_attrs = html_attrs.smart_merge(
|
22
22
|
class: 'border border-primary-500', data: { controller: 'slideover' }, href: '#'
|
@@ -28,6 +28,7 @@ html_attrs = html_attrs.smart_merge(
|
|
28
28
|
data: { controller: 'popover slideover', action: 'click->popover#toggle' },
|
29
29
|
href: '#'
|
30
30
|
}
|
31
|
+
# Note: #smart_merge returns an HtmlAttrs object which is a subclass of Hash, so you can use it just like a hash.
|
31
32
|
```
|
32
33
|
|
33
34
|
You can use this in helpers that accept HTML attributes as a hash, e.g:
|
@@ -62,7 +63,35 @@ You can also use the `to_s` method to get the string representation of the HTML
|
|
62
63
|
</a>
|
63
64
|
```
|
64
65
|
|
66
|
+
Merging is done recursively:
|
67
|
+
* Strings are merged by concatenating them with a space.
|
68
|
+
* Arrays are merged with simple concatenation.
|
69
|
+
* Hashes are merged recursively using the above rules.
|
70
|
+
* Everything else is merged normally, just like with `Hash#merge`.
|
71
|
+
|
72
|
+
Super simple, but super powerful.
|
73
|
+
|
74
|
+
If one hash that has a string key and the other has a symbol key or vice-versa, we'll convert everything to whatever the first hash has.
|
75
|
+
|
76
|
+
## Configuring mergeable attributes
|
77
|
+
|
78
|
+
By default, this gem merges `class`, `style` and `data` attributes recursively. Which should usually be more than enough. You can easily customize this by specifying `mergeable_attributes:` when calling `smart_merge`. e.g:
|
79
|
+
```ruby
|
80
|
+
HtmlAttrs.new(class: 'bg-primary-500', id: 'test', aria_label: 'Help')
|
81
|
+
.smart_merge(aria_label: 'Another', href: '/test', mergeable_attributes: [:aria_label])
|
82
|
+
# => { class: 'bg-primary-500', id: 'test', aria_label: 'Help Another', href: '/test' }
|
83
|
+
```
|
84
|
+
|
85
|
+
You can also just set `mergeable_attributes: :all` to merge everything. Or you can just use `smart_merge_all` which merges everything by default.
|
65
86
|
|
87
|
+
```ruby
|
88
|
+
{ class: 'bg-primary-500', id: 'test', aria_label: 'Help' }
|
89
|
+
.smart_merge_all(class: 'text-red-500', aria_label: 'Another', href: '/test')
|
90
|
+
# => { class: 'bg-primary-500 text-red-500', id: 'test', aria_label: 'Help Another', href: '/test' }
|
91
|
+
```
|
92
|
+
|
93
|
+
|
94
|
+
## Other ways to use
|
66
95
|
Alternative, you can use the `HtmlAttrs` class directly, e.g:
|
67
96
|
```ruby
|
68
97
|
HtmlAttrs.smart_merge(
|
@@ -81,18 +110,18 @@ html_attrs.smart_merge( id: 'test', class: 'border')
|
|
81
110
|
# => { class: 'bg-primary-500 border', data: { controller: 'popover' }, id: 'test' }
|
82
111
|
```
|
83
112
|
|
84
|
-
Under the hood, `HtmlAttrs` is a simple wrapper around `
|
113
|
+
Under the hood, `HtmlAttrs` is a simple wrapper around `Hash`, so you can use it just like any other hash. The only difference is `#smart_merge`, `#smart_merge_all` and `to_s`.
|
85
114
|
|
86
|
-
|
115
|
+
<br/>
|
87
116
|
|
88
|
-
##
|
117
|
+
## Interested in a powerful Rails UI library?
|
89
118
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
119
|
+
I am working on a super-powerful Rails UI library - components as well as templates & patterns.
|
120
|
+
|
121
|
+
[Please check this out if you're interested](https://owaiskhan.me/rails-ui-library).
|
122
|
+
<br/>
|
123
|
+
<br/>
|
124
|
+
<br/>
|
96
125
|
|
97
126
|
## Development
|
98
127
|
|
data/lib/html_attrs.rb
CHANGED
@@ -1,16 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'action_view'
|
4
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
5
4
|
|
6
|
-
class HtmlAttrs <
|
7
|
-
VERSION = '1.
|
5
|
+
class HtmlAttrs < Hash
|
6
|
+
VERSION = '1.1.0'
|
8
7
|
DEFAULT_MERGEABLE_ATTRIBUTES = %i[class style data].to_set
|
9
8
|
|
10
|
-
def
|
11
|
-
|
9
|
+
def initialize(constructor = nil)
|
10
|
+
if constructor.respond_to?(:to_hash)
|
11
|
+
super()
|
12
|
+
update(constructor)
|
13
|
+
|
14
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
15
|
+
self.default = hash.default if hash.default
|
16
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
17
|
+
elsif constructor.nil?
|
18
|
+
super()
|
19
|
+
else
|
20
|
+
super(constructor)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def smart_merge(target)
|
25
|
+
if target.is_a?(Hash) && target.key?(:mergeable_attributes)
|
26
|
+
mergeable_attributes = target.delete(:mergeable_attributes)
|
27
|
+
end
|
12
28
|
mergeable_attributes ||= DEFAULT_MERGEABLE_ATTRIBUTES
|
13
|
-
self.class.smart_merge(self,
|
29
|
+
self.class.smart_merge(self, target, mergeable_attributes: mergeable_attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def smart_merge_all(target)
|
33
|
+
target[:mergeable_attributes] = :all if target.is_a?(Hash)
|
34
|
+
smart_merge(target)
|
14
35
|
end
|
15
36
|
|
16
37
|
def to_s
|
@@ -18,37 +39,48 @@ class HtmlAttrs < HashWithIndifferentAccess
|
|
18
39
|
end
|
19
40
|
|
20
41
|
def self.smart_merge(other, target, mergeable_attributes: DEFAULT_MERGEABLE_ATTRIBUTES)
|
21
|
-
other = other.with_indifferent_access if other.is_a?(Hash) && !other.is_a?(HashWithIndifferentAccess)
|
22
|
-
target = target.with_indifferent_access if target.is_a?(Hash) && !target.is_a?(HashWithIndifferentAccess)
|
23
|
-
|
24
42
|
return other if target.nil?
|
25
43
|
return target if other.nil?
|
26
44
|
|
27
45
|
if target.is_a?(Hash) || other.is_a?(Hash)
|
28
|
-
raise 'Expected target to be a hash or nil'
|
29
|
-
raise 'Expected other to be a hash or nil'
|
46
|
+
raise 'Expected target to be a hash or nil' unless target.is_a?(Hash)
|
47
|
+
raise 'Expected other to be a hash or nil' unless other.is_a?(Hash)
|
48
|
+
|
49
|
+
other = other.dup
|
50
|
+
target = target.dup
|
30
51
|
|
31
52
|
target.each do |key, value|
|
32
|
-
|
33
|
-
|
34
|
-
|
53
|
+
other_type_of_key = key.is_a?(Symbol) ? key.to_s : key.to_sym
|
54
|
+
|
55
|
+
key_with_value = if other.key?(key)
|
56
|
+
key
|
57
|
+
elsif other.key?(other_type_of_key)
|
58
|
+
other_type_of_key
|
59
|
+
else
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
other[key_with_value || key] =
|
64
|
+
if key_with_value && attribute_mergeable?(key, mergeable_attributes)
|
65
|
+
smart_merge(other[key_with_value], value, mergeable_attributes: :all)
|
35
66
|
else
|
36
67
|
value
|
37
68
|
end
|
38
69
|
end
|
70
|
+
|
39
71
|
return other
|
40
72
|
end
|
41
73
|
|
42
74
|
if target.is_a?(Array) || other.is_a?(Array)
|
43
|
-
raise 'Expected target to be an array or nil'
|
44
|
-
raise 'Expected other to be an array or nil'
|
75
|
+
raise 'Expected target to be an array or nil' unless target.is_a?(Array)
|
76
|
+
raise 'Expected other to be an array or nil' unless other.is_a?(Array)
|
45
77
|
|
46
|
-
return (other || []).concat(target || [])
|
78
|
+
return (other.dup || []).concat(target.dup || [])
|
47
79
|
end
|
48
80
|
|
49
81
|
if target.is_a?(String) || other.is_a?(String)
|
50
|
-
raise 'Expected target to be a string or nil'
|
51
|
-
raise 'Expected other to be a string or nil'
|
82
|
+
raise 'Expected target to be a string or nil' unless target.is_a?(String)
|
83
|
+
raise 'Expected other to be a string or nil' unless other.is_a?(String)
|
52
84
|
|
53
85
|
return [other.presence, target.presence].compact.join(' ')
|
54
86
|
end
|
@@ -56,6 +88,10 @@ class HtmlAttrs < HashWithIndifferentAccess
|
|
56
88
|
target
|
57
89
|
end
|
58
90
|
|
91
|
+
def self.smart_merge_all(other, target)
|
92
|
+
smart_merge(other, target, mergeable_attributes: :all)
|
93
|
+
end
|
94
|
+
|
59
95
|
def self.attribute_mergeable?(attribute, mergeable_attributes)
|
60
96
|
return true if mergeable_attributes == :all
|
61
97
|
|
@@ -75,4 +111,12 @@ class Hash
|
|
75
111
|
def as_html_attrs
|
76
112
|
HtmlAttrs.new(self)
|
77
113
|
end
|
114
|
+
|
115
|
+
def smart_merge(target)
|
116
|
+
as_html_attrs.smart_merge(target)
|
117
|
+
end
|
118
|
+
|
119
|
+
def smart_merge_all(target)
|
120
|
+
as_html_attrs.smart_merge_all(target)
|
121
|
+
end
|
78
122
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html_attrs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Owais
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionview
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '6.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: activesupport
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '6.0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '6.0'
|
41
27
|
description: A gem that provides a way to smartly merge HTML attributes
|
42
28
|
email:
|
43
29
|
- owaiswiz@gmail.com
|