# HtmlAttrs A simple gem to merge HTML attributes in Ruby. It's incredibly useful when you're working with HTML attributes in a Rails app. For example, you're accepting arguments in a component or partial from somewhere else that you then need to merge smartly (can be tailwind classes, data attributes for stimulus controllers, etc) ## Installation Install the gem and add to the application's Gemfile by executing: ```shell $ bundle add html_attrs ``` ## Usage ```ruby html_attrs = { class: 'bg-primary-500', data: { controller: 'popover', action: 'click->popover#toggle' } } html_attrs = html_attrs.smart_merge( class: 'border border-primary-500', data: { controller: 'slideover' }, href: '#' ) # Will produce: { class: 'bg-primary-500 border border-primary-500', data: { controller: 'popover slideover', action: 'click->popover#toggle' }, href: '#' } # Note: #smart_merge returns an HtmlAttrs object which is a subclass of Hash, so you can use it just like a hash. ``` You can use this in helpers that accept HTML attributes as a hash, e.g: ```erb <%= content_tag(:a, 'Hello', html_attrs) %> <%# Will produce: %> Hello ``` You can also use the `to_s` method to get the string representation of the HTML attributes, if you need to use it in a string context. ```erb id='home'>Hello <%# Will produce: %> Hello ``` Merging is done recursively: * Strings are merged by concatenating them with a space. * Arrays are merged with simple concatenation. * Hashes are merged recursively using the above rules. * Everything else is merged normally, just like with `Hash#merge`. Super simple, but super powerful. 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. ## Configuring mergeable attributes 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: ```ruby HtmlAttrs.new(class: 'bg-primary-500', id: 'test', aria_label: 'Help') .smart_merge(aria_label: 'Another', href: '/test', mergeable_attributes: [:aria_label]) # => { class: 'bg-primary-500', id: 'test', aria_label: 'Help Another', href: '/test' } ``` You can also just set `mergeable_attributes: :all` to merge everything. Or you can just use `smart_merge_all` which merges everything by default. ```ruby { class: 'bg-primary-500', id: 'test', aria_label: 'Help' } .smart_merge_all(class: 'text-red-500', aria_label: 'Another', href: '/test') # => { class: 'bg-primary-500 text-red-500', id: 'test', aria_label: 'Help Another', href: '/test' } ``` ## Other ways to use Alternative, you can use the `HtmlAttrs` class directly, e.g: ```ruby HtmlAttrs.smart_merge( { class: 'bg-primary-500', data: { controller: 'popover' } }, { id: 'test', class: 'border' } ) # => { class: 'bg-primary-500 border', data: { controller: 'popover' }, id: 'test' } ``` Or, you can also instantiate a new `HtmlAttrs` object and use the `smart_merge` method, e.g: ```ruby html_attrs = HtmlAttrs.new(class: 'bg-primary-500', data: { controller: 'popover' }) # => { class: 'bg-primary-500', id: 'test', aria_label: 'Help', download: 'test.jpeg' } html_attrs.smart_merge( id: 'test', class: 'border') # => { class: 'bg-primary-500 border', data: { controller: 'popover' }, id: 'test' } ``` 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`.
## Interested in a powerful Rails UI library? I am working on a super-powerful Rails UI library - components as well as templates & patterns. [Please check this out if you're interested](https://owaiskhan.me/rails-ui-library).


## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/owaiswiz/html_attrs. ## License The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).